-*- buffer-read-only: t -*- #+auto_tangle: t #+PROPERTY: header-args:elisp+ :tangle ~/.emacs.d/init.el #+PROPERTY: header-args:elisp+ :results none #+PROPERTY: header-args:elisp+ :lexical t #+PROPERTY: header-args:elisp+ :noweb-sep "\n\n" #+OPTIONS: html-style:nil * 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. See the end of this file for the elisp block that tangles out to init.el. Here is a preamble that ends up at the top of init.el This preamble sets a few variables that control how Emacs behaves more generally. #+name: preamble #+begin_src elisp :noweb no-export ;;; PREAMBLE (setq custom-file (concat user-emacs-directory "../notes/custom.el")) (load custom-file 'noerror) (setq backup-directory-alist '(("." . "~/.emacs.d/backups"))) (setq backup-by-copying t) (setq warning-minimum-level :emergency) ;;; utilities (defun read-file-into-string (f) (with-temp-buffer (insert-file-contents f) (buffer-string))) (defun middle-of-list (xs) (elt xs (/ (length xs) 2))) #+end_src ** Native Compilation New in emacs 28, native compilation can be enabled. I have attempted to disable it. #+name: native-comp #+begin_src elisp :results none ;; Native compilation setup (when (and (fboundp 'native-comp-available-p) (native-comp-available-p)) (setq package-native-compile nil native-comp-always-compile nil)) #+end_src ** Packages Setup Config I'm using melpa and elpa package archives. #+name: packages-setup-config #+begin_src elisp :results none ;; PACKAGES SETUP (require 'cl) (defun my-package-install (package &optional archive dont-select) "archive is a string naming the archive. Will attempt" (let* ((pkg-descs (cdr (assoc package package-archive-contents))) (desc (if archive (find archive pkg-descs :test 'equalp :key 'package-desc-archive)))) (when desc (package-install desc dont-select)))) (require 'package) (add-to-list 'package-archives '("elpa" . "https://elpa.gnu.org/packages/") t) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) ;(package-refresh-contents) (package-install 'use-package) #+end_src * Leader Keys I have written a custom leader key system called "my-leader-keys". A leader key system provides keyboard driven menus for executing emacs commands a.k.a "interactive functions". An initial key (=M-m= for me) opens the top level menu. The menu presents keys to press that either lead to the further menus or that run a specific interactive 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 initial 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 '((?/ "[/] swiper" swiper) ;(?? "[?] imenu" imenu-list) (?? "[?] replace" query-replace) (?e "[e]diting" my-special-edit-command) (?' "['] shell" persp-shell--jump-to-persp-shell) (?b "[b]uffers" my-buffer-command) (?c "[c]apture" org-capture) (?a "[a]pplications" my-utilities-command) (?t "[t]hemes" my-theme-cycler) (?T "[T]heme set" toggle-theme-set) (?l "[l]ayouts" my-perspective-command) (?w "[w]indows" my-window-comand) (?p "[p]roject" my-projectile-command) (?m "[m]ajor" my-major-mode-command) (?f "[f]ind-file" find-file) (?d "[d]ired" dired) ;(?d "[d]irvish" dirvish) (?r "[r]eading" my-reading-command) (?s "[s]ly" sly) (?h "[h]elp" helpful-at-point))) (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 ;; major mode leaader keys (defvar my-major-mode-list nil "subcommands by major-mode") (setf my-major-mode-list '((org-mode my-org-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]omodoro" pomidor) (?w "[w]eb browser (eww)" eww) (?C "[C]RDT" my-crdt-commands) (?t "[t]asks" list-cicadas-tasks))) #+end_src * Org Mode Configs ** Org Mode Main Config #+name: org-mode-main-config #+begin_src elisp :noweb no-export :results none ;; org mode config (package-install 'org) (require 'org) (setq org-duration-format 'h:mm) (setq org-edit-src-content-indentation 0) (setq org-goto-interface 'outline-path-completion org-goto-max-level 10 org-outline-path-complete-in-steps nil) (setq org-imenu-depth 10) (setq org-startup-folded t) (defun my-org-up-heading () (interactive) (org-up-heading-safe)) (defun my-org-down-heading () (interactive) (org-down-element)) (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 no-export\n\n#+end_src" lang))) #+end_src #+RESULTS: org-mode-main-config ** My-Leader Key for Org Major Mode #+name: org-mode-leader-key-menu #+begin_src elisp :results none :noweb no-export ;; org mode leader keys and related commands (defun org-src--source-buffer () (marker-buffer org-src--beg-marker)) (defun buffer-read-only-p (buffer) "Returns T if BUFFER, which can be a name or a buffer, is read only." (buffer-local-value 'buffer-read-only (get-buffer buffer))) (defvar org-src--read-only-source-buffer-cache nil "") (defun before-org-edit-src-exit (&rest args) "If necessary, make the org src buffer's target buffer writable prior to exiting." (let ((target-buffer (org-src--source-buffer))) (when (buffer-read-only-p target-buffer) (setf org-src--read-only-source-buffer-cache target-buffer) (with-current-buffer target-buffer (read-only-mode 0))))) (defun after-org-edit-src-exit (&rest args) "If necessary, make the org src buffer's target buffer read-only again, if it was whent he org edit src buffer was opened." (when org-src--read-only-source-buffer-cache (with-current-buffer org-src--read-only-source-buffer-cache (read-only-mode 1)) (setf org-src--read-only-source-buffer-cache nil))) (advice-add 'org-edit-src-exit :before #'before-org-edit-src-exit) (advice-add 'org-edit-src-exit :after #'after-org-edit-src-exit) (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) (?p "[p]revious heading" org-previous-visible-heading) (?n "[n]next heading" org-next-visible-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) (?x "e[x]port" 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" org-clock-in))) (def-my-command my-org-export-subcommand '((?t "[t]angle file" org-babel-tangle) (?w "[w]ritefreely" writefreely-publish-or-update) (?x "e[x]port 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) (?r "insert d[r]awe[r]" org-insert-drawer) (?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 * UI ** Fonts #+name: ui-fonts #+begin_src elisp :noweb no-export ;; fonts (add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono-10") ;'(font . "Comic Mono-11") ;'(font . "Victor Mono-10") ;; uhh ) #+end_src #+RESULTS: ui-fonts : ((font . Comic Mono-10) (font . Victor Mono-10) (vertical-scroll-bars) (left-fringe . 4) (right-fringe . 0)) ** 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 ** 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 keys (global-unset-key (kbd "")) (global-unset-key "\C-z") (setq-default indent-tabs-mode nil) ;(global-hl-line-mode 1) #+end_src ** Completions Engine #+name: ui-completion-engine #+begin_src elisp :results none ;; command completions (package-install 'ivy) ;(package-install 'smex) (package-install 'amx) (package-install 'swiper) (ivy-mode 1) (setq ivy-use-selectable-prompt t) (amx-mode) ;(smex-initialize) ;(global-set-key (kbd "M-x") 'smex) #+end_src ** Buffers, Windows, and Perspectives *** Packages #+name: ui-windows-and-perspectives-packages #+begin_src elisp :results none (package-install 'perspective) (setq persp-suppress-no-prefix-key-warning t) (persp-mode 1) (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)) (setq *auto-light-mode* nil) (defun toggle-auto-light-mode () (interactive) (set-frame-parameter nil 'screen-gamma (if *auto-light-mode* 2.2 3.1)) (setq *auto-light-mode* (not *auto-light-mode*))) (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) (?l "[l]ightmode toggle" toggle-auto-light-mode) (?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 ** Modeline #+name: modeline-config #+begin_src elisp :noweb no-export :results none (package-install 'feline) (use-package feline :config (feline-mode) :custom (feline-mode-symbols '(emacs-lisp-mode "eλ" lisp-interaction-mode "eλ" shell-mode "🖳" lisp-mode "λ" org-mode "🌳" python-mode "🐍"))) #+end_src ** Themes *** Installed Themes #+name: ui-themes-installed #+begin_src elisp :results none (package-install 'autothemer) ;; for custom themes (setq my-installed-themes '(pastelmac-theme poet-theme flexoki-themes soft-morning-theme goose-theme naga-theme grandshell-theme nimbus-theme morgentau-theme)) (dolist (package my-installed-themes) (when (not (package-installed-p package)) (package-install package))) #+end_src *** Theme Switcher #+name: ui-themes-theme-switcher #+begin_src elisp :results none (defun themes-in-package (package) "PACKAGE is a symbol naming a particular theme package. Return a list of symbols naming the themes in that package, if there are any. Each such symbol returned is suitable for passing to LOAD-THEME" (let* ((package-search-string (format "elpa/%s" package)) (package-dir (cl-find-if (lambda (dir) (cl-search package-search-string dir)) (custom-theme--load-path))) (suffix "-theme\\.el\\'")) (when package-dir (remove-if-not 'custom-theme-p (mapcar (lambda (file) (load-file (format "%s/%s" package-dir file)) (intern (substring file 0 (string-match-p suffix file)))) (directory-files package-dir nil suffix)))))) (defun toggle-theme-set () (interactive) (if (equalp *current-theme-set* *coding-themes*) (setq *current-theme-set* *writing-themes*) (setq *current-theme-set* *coding-themes*)) (my-theme-command-next)) (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]revious. 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]revious. Anything else to quit." (my-theme-string)))))) (defun my-theme-linum-mode-cycler () "sometimes cycling themes when linum mode is on causes screwy display. cycling helps." (when (and (boundp 'linum-mode) (symbol-value linum-mode)) (linum-mode -10) (linum-mode))) (defun my-theme-command-next () (interactive) (let* ((active-theme (car custom-enabled-themes)) (next-theme (cadr (cl-member active-theme *current-theme-set*)))) (when active-theme (disable-theme active-theme)) (if next-theme (load-theme next-theme t) (load-theme (car *current-theme-set*) t)) (setq cursor-type 'box) (setq-default cursor-type 'box) (my-theme-linum-mode-cycler))) (defun my-theme-command-previous () (interactive) (let* ((active-theme (car custom-enabled-themes)) (themes (reverse *current-theme-set*)) (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) (my-theme-linum-mode-cycler))) #+end_src *** Choice Themes #+name: ui-themes-choice-themes #+begin_src elisp :noweb no-export :results none (setq *coding-themes* '( ;; light pastelmac flexoki-themes-light ;; medium goose morgentau nimbus ;; dark grandshell flexoki-themes-dark naga)) (setq *writing-themes* (themes-in-package 'poet)) (setq *current-theme-set* *coding-themes*) (when (car custom-enabled-themes) (disable-theme (car custom-enabled-themes))) (load-theme (middle-of-list *current-theme-set*) t) #+end_src #+RESULTS: ui-themes-choice-themes | poet-dark-monochrome | poet-dark | poet-monochrome | poet | * Time Managment #+name: time-management-preamble #+begin_src elisp :noweb no-export :results none (setq org-enforce-todo-dependencies t org-enforce-todo-checkbox-dependencies t) (setq org-edit-src-content-indentation 0) #+end_src ** Pomidor Pomidor is a neat pomidoro system that I started using recently. I don't care about the productity aspect, but I like the reminders to stand up and move around. #+name: pomidor #+begin_src elisp :noweb no-export :results none (package-install 'pomidor) (setq pomidor-seconds (* 60 60) pomidor-break-seconds (* 15 60) pomidor-breaks-before-long 1000 pomidor-sound-tick nil pomidor-sound-tack nil) #+end_src ** CALFW calendar #+name: calfw-org-config #+begin_src elisp :noweb no-export :results none (package-install 'calfw) (package-install 'calfw-org) (require 'calfw) (require 'calfw-org) (custom-set-variables '(cfw:org-capture-template '("c" "Calendar" entry (file+headline "~/notes/deft/project-Planner.org" "CALENDAR") "* %?\n %(cfg:org-capture-day)"))) #+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 ( ("w" "Web Clip" entry (file+olp+datetree "~/notes/deft/Web.org" "Weblink") "* TOREAD %:annotation \n\n#+begin_quote\n\n%i\n\n#+end_quote\n\n" :immediate-finish t :empty-lines 1 :prepend t) ("l" "Web Link" entry (file+olp+datetree "~/notes/deft/Web.org" "Weblink") "* TOREAD %:annotation" :immediate-finish t :empty-lines 1 :prepend t) ("n" "Note" entry (file+olp "~/notes/deft/project-Planner.org" "Notes") "* %U\n\n %F\n\n" :prepend t :empty-lines 1) ("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)")))) #+end_src ** Org Agenda #+name: org-agenda-config #+begin_src elisp :noweb no-export :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 * Communication ** ERC #+name: erc-config #+begin_src elisp :noweb no-export :results none (setq erc-hide-list '("JOIN" "QUIT" "PART")) #+end_src * Reading, Notes, and Writing ** General Reading Tools wordnut is a wordnet interface #+name: general-reading-tools #+begin_src elisp :noweb no-export :results none (package-install 'wordnut) (def-my-command my-reading-command '((?l "[l]ookup word" wordnut-lookup-current-word) (?L "[L]ookup any word" wordnut-search))) #+end_src imenu-list displayes imenu results in a a navigable table-of-contents tree-like format. #+name: imenu-list #+begin_src elisp :noweb no-export (package-install 'imenu-list) #+end_src ** Calibre db #+name: calibre-config #+begin_src elisp :results none (package-install 'calibredb) (require 'calibredb) (setq calibredb-root-dir "~/Calibre") (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 #+name: nov #+begin_src elisp :noweb no-export :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-db-directory "~/notes/dot-elfeed") (setq elfeed-feeds '(("https://harpers.org/feed" culture politics news) ("https://theconvivialsociety.substack.com/feed" technology culture philosophy) ("https://www.bostonreview.net/topics/philosophy-religion/feed" philosophy) ("https://www.bostonreview.net/topics/class-inequality/feed" politics) ("https://thepointmag.com/feed/" culture philosophy) ("https://www.merriam-webster.com/wotd/feed/rss2" wordoday))) (setq-default elfeed-search-filter "@2-weeks-ago +unread") #+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") ;; no longer needed, I just put the buffer-local variable setting at ;; the top of the file. REmains for posterity. ;; (defun toggle-secrets-readonly () ;; (interactive) ;; (toggle-secrets) ;; (when (equal (buffer-name) "secrets.org.cpt") ;; (read-only-mode))) #+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-dark) ;; (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 no-export :results none (setq browse-url-browser-function 'eww-browse-url) ;; (add-hook 'eww-mode-hook ;; (lambda () ;; (writeroom-mode t))) #+end_src ** Markdown Editing #+name: markdown-editing #+begin_src elisp :noweb no-export (package-install 'markdown-mode) #+end_src #+RESULTS: markdown-editing ** My leader key special edit commands Little utils for editing. =my-freaking-align= tries to align lines of text into columns. =my-special-insert= presents a menu for inserting common unicode characters. #+name: my-leader-special-edit #+begin_src elisp :noweb no-export :results none (defun my-freaking-align () (interactive) (align-regexp (region-beginning) (region-end) "\\(\\s-*\\)\\s-" 1 1 t) (indent-region (region-beginning) (region-end))) (def-my-command my-special-edit-command '( (?i "[i]nsert" my-special-insert) (?a "[a]lign" my-freaking-align))) #+end_src *** My leader key Special inserts Included are common greekletters, arrows, logical symbols and some math symbols. #+name: my-special-inserts #+begin_src elisp :noweb no-export :results none (defun inserter (what) (lexical-let ((what what)) (lambda () (interactive) (insert what)))) (def-my-command my-special-insert `((?l "[l] λ" ,(inserter "λ")) (?a "[a] α" ,(inserter "α")) (?b "[b] β" ,(inserter "β")) (?g "[g] γ" ,(inserter "γ")) (?p "[p] π" ,(inserter "π")) (?f "[f] φ" ,(inserter "φ")) (?^ "[^] ↑" ,(inserter "↑")) (?v "[v] ↓" ,(inserter "↓")) (?> "[>] →" ,(inserter "→")) (?< "[<] ←" ,(inserter "←")) (?A "[A] ∀" ,(inserter "∀")) (?E "[E] ∃" ,(inserter "∃")) (?. "[.] ·" ,(inserter "·")) (?x "[x] ×" ,(inserter "×")) (?X "[X] ⊗" ,(inserter "⊗")) (?+ "[+] ⊕" ,(inserter "⊕")) (?/ "[/] ÷" ,(inserter "÷")) (?U "[U] ∪" ,(inserter "∪")) (?I "[I] ∩" ,(inserter "∩")) (?& "[&] ∧" ,(inserter "∧")) (?| "[|] ∨" ,(inserter "∨")))) #+end_src #+RESULTS: my-special-inserts : my-special-insert * Software Development #+name: software-development-preamble #+begin_src elisp :noweb no-export :results none (show-paren-mode 1) (which-function-mode 1) #+end_src ** Literate Programming Hacks and tweaks for literate programming. Org auto tangle will tangle a file whenever it is saved. This is also where I have placed the various configs for evaluating code in emacs org blocks. #+name: literate-programming #+begin_src elisp :noweb no-export (package-install 'org-auto-tangle) (require 'org-auto-tangle) (add-hook 'org-mode-hook 'org-auto-tangle-mode) (package-install 'jupyter) (load "~/notes/elisp/ox-ipynb.el") (require 'ox-ipynb) (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (python . t) (lisp . t) (C . t) (shell . t) ;(jupyter . t) )) (setf org-src-window-setup 'current-window) ;; this is a hack to get syntax highlighting. The problem is that ;; newer orgs don't know what to do with `#+begin_src jupyter-python`, ;; so I just have to do `#+begin_src jupyter`, but then there's no ;; syntax highlighting ;; (define-derived-mode jupyter-mode python-mode "Python" ;; "Haxe syntax highlighting mode. This is simply using js-mode for now.") #+end_src #+RESULTS: literate-programming : current-window ** Pair-Programming *** CRDT for pair programming #+name: crdt-config #+begin_src elisp :results none (package-install 'crdt) (def-my-command my-crdt-commands '((?s "[s]hare this buffer" crdt-share-buffer) (?f "[f]ollow a user" crdt-follow-user) (?u "[u]nfollow a user" crdt-stop-follow) (?C "[C]lose connection" crdt-disconnect) (?c "[c]onnect" crdt-connect) (?l "[l]ist buffers" crdt-list-buffers))) #+end_src ** Tools Essential To Development #+name: software-dev-essentials #+begin_src elisp :noweb no-export :results none (package-install 'company) (package-install 'magit) (require 'company) (global-company-mode 1) ;; see https://github.com/magit/magit/issues/5011 (require 'seq-25) (package-install 'ag) #+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 'native) (setq org-duration-format 'h:mm) (def-my-command my-projectile-command '((?/ "[/] search project" projectile-ag) (?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 ** Shell Config The following defines commands used by my leader key ssytem to association one shell with each perspective layout #+name: shell-config #+begin_src elisp :noweb no-export :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 ** Common Lisp *** Packages #+name: common-lisp-packages #+begin_src elisp :results none (package-install 'paredit) (package-install 'sly) #+end_src *** Sly #+name: sly-config #+begin_src elisp :noweb no-export (def-my-command my-lisp-mode-command '((?d "[d]ocumentation" sly-describe-symbol) ;(?\t "[TAB] inspect" how do I inspect??? ) (?S "[S]ync package" sly-mrepl-sync) (?\t "TAB inpsect" sly-inspect))) ;; (defvar +symbols-in-cl+ 977) ;; (defun slime-random-words-of-encouragement () ;; "Return a string of hackerish encouragement." ;; (slime-eval ;; `(swank:documentation-symbol ;; (cl:loop :for name :being :each :symbol :in (cl:find-package "CL") ;; :collect (cl:symbol-name name) :into names ;; :finally (cl:return (cl:elt names ,(random +symbols-in-cl+))))))) ;; (defun slime-fasl-directory () ;; (let ((dir (format "%s/.cache/slime-fasls/" (getenv "HOME")))) ;; (make-directory dir t) ;; dir)) ;; (setq slime-compile-file-options ;; (list :fasl-directory (slime-fasl-directory))) #+end_src *** Editing Config #+name: common-lisp-editing-config #+begin_src elisp :results none (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 'lisp-mode-hook #'enable-paredit-mode) (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode) (add-hook 'scheme-mode-hook #'enable-paredit-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)) (add-hook 'lisp-mode-hook 'linum-mode) (setq +common-lisp-package-template+ " (defpackage #:%s (:use #:cl)) (in-package #:%s) ") (defun insert-cl-defpackage (name) (interactive "sName: ") (insert (format +common-lisp-package-template+ name name))) (with-eval-after-load 'lisp-mode (progn (setq common-lisp-hyperspec-root "file:///home/colin/HyperSpec/"))) #+end_src *** Coalton #+name: coalton-config #+begin_src elisp :noweb no-export (setq +coalton-package-template+ " (defpackage #:%s (:import-from #:common-lisp #:describe #:disassemble) (:use #:coalton #:coalton-prelude) (:local-nicknames (#:types #:coalton-library/types) (#:hash #:coalton-library/hash) (#:bits #:coalton-library/bits) (#:math #:coalton-library/math) (#:char #:coalton-library/char) (#:string #:coalton-library/string) (#:tuple #:coalton-library/tuple) (#:optional #:coalton-library/optional) (#:list #:coalton-library/list) (#:result #:coalton-library/result) (#:cell #:coalton-library/cell) (#:vector #:coalton-library/vector) (#:slice #:coalton-library/slice) (#:hashtable #:coalton-library/hashtable) (#:st #:coalton-library/monad/state) (#:free #:coalton-library/monad/free) (#:iter #:coalton-library/iterator) (#:sys #:coalton-library/system))) (named-readtables:in-readtable coalton:coalton) (in-package #:%s) (coalton-toplevel ) ") (defun insert-coalton-defpackage (name) (interactive "sName: ") (insert (format +coalton-package-template+ name name))) #+end_src #+RESULTS: coalton-config : insert-coalton-defpackage #+RESULTS: coalton : insert-coalton-defpackage ** Haxe #+name: haxe-config #+begin_src elisp :noweb no-export (package-install 'haxe-mode) #+end_src #+RESULTS: haxe-config : ‘haxe-mode’ is already installed ** COMMENT Python #+name: python-config #+begin_src elisp :noweb no-export :results none (package-install 'pyvenv) (setenv "WORKON_HOME" "~/miniconda3/envs") (pyvenv-mode 1) (package-install 'elpy) (elpy-enable) (setq python-shell-interpreter "jupyter" python-shell-interpreter-args "console --simple-prompt" python-shell-prompt-detect-failure-warning nil) (add-to-list 'python-shell-completion-native-disabled-interpreters "jupyter") #+end_src #+RESULTS: python-config :results none #+RESULTS: python-config * Tools ** Export Emacs Buffer #+name: buffer-export-config #+begin_src emacs-lisp (defun screenshot-svg (filename) "Save a screenshot of the current frame as an SVG image. Saves to a temp file and puts the filename in the kill ring." (interactive "sfilename:") (let* ((tmpfile (make-temp-file "Emacs" nil ".svg")) (data (x-export-frames nil 'svg))) (with-temp-file tmpfile (insert data)) (copy-file tmpfile filename t) (message filename))) #+end_src #+RESULTS: buffer-export-config : screenshot-svg ** Helpful #+name: helpful #+begin_src elisp :noweb no-export (package-install 'helpful) #+end_src #+RESULTS: helpful : Package ‘helpful’ installed. * External Loads #+name: loads #+begin_src elisp :noweb no-export (load "~/.emacs.d/cicadas-config.el") (load "~/projects/cicadas.org/cicatasks.el") #+end_src