-- buffer-read-only: t --

1 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.

(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)
    (insert-file-contents f)

(defun middle-of-list (xs)
  (elt xs (/ (length xs) 2)))

1.1 Native Compilation

New in emacs 28, native compilation can be enabled. I have attempted to disable it.

;; Native compilation setup

(when (and (fboundp 'native-comp-available-p)
  (setq package-native-compile t
        native-comp-always-compile t))

1.2 Packages Setup Config

I'm using melpa and elpa package archives.

(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)))
          (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-install 'use-package)

2 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.

2.1 My Leader Keys Definition

;; 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*))
                      ", ")))

2.2 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.

;; 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)

2.3 My leader Key Major Mode Menu

;; 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)
        (sly-mrepl-mode my-lisp-mode-command)))

(defun my-major-mode-command ()
  (let ((mode-command (assoc major-mode my-major-mode-list)))
    (when mode-command
      (call-interactively (cadr mode-command)))))

2.4 My leader key utilities and applications menu

(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)))

3 Org Mode Configs

3.1 Org Mode Main Config

;; 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 ()

(defun my-org-down-heading ()

(defun personal-log-insert ()
  (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)))

3.2 My-Leader Key for Org Major Mode

;; 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)))

4 UI

4.1 Fonts

;; fonts

(add-to-list 'default-frame-alist
             '(font . "DejaVu Sans Mono-10")
             ;'(font . "Comic Mono-11")
             ;'(font . "Victor Mono-10") ;; uhh

4.2 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.

;; UI Chrome

(blink-cursor-mode 0)
(setq-default cursor-type 'box)
(menu-bar-mode 0)
(tool-bar-mode 0)
(scroll-bar-mode -1)

(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))

4.3 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.

;; global keys

(global-unset-key (kbd "<Scroll_Lock>"))
(global-unset-key "\C-z") 
(setq-default indent-tabs-mode nil) 
;(global-hl-line-mode 1)

4.4 Completions Engine

;; command completions 

(package-install 'ivy)
;(package-install 'smex)
(package-install 'amx)
(package-install 'swiper)
(ivy-mode 1)
(setq ivy-use-selectable-prompt t)

;(global-set-key (kbd "M-x") 'smex)

4.5 Buffers, Windows, and Perspectives

4.5.1 Packages

(package-install 'perspective)
(setq persp-suppress-no-prefix-key-warning t)
(persp-mode 1)

(package-install 'rotate)

(package-install 'window-numbering)

(package-install 'resize-window)
(require 'resize-window)

4.5.2 Window Leader Key Menu

(setq fit-window-to-buffer-horizontally t)

(defun my-fit-window-to-buffer ()

(setq *auto-light-mode* nil)

(defun toggle-auto-light-mode ()
   nil 'screen-gamma
   (if *auto-light-mode*
  (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)))

4.5.3 Buffer Leader Key Menu

(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)))

4.5.4 Perspectives Leader Key Menu

(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)))

4.6 Modeline

(package-install 'feline)

(use-package feline
  :config (feline-mode)
   '(emacs-lisp-mode "eλ"
     lisp-interaction-mode "eλ"
     shell-mode "🖳"
     lisp-mode "λ"
     org-mode "🌳"
     python-mode "🐍")))

4.7 Themes

4.7.1 Theme Switcher

(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
  (let* ((package-search-string
          (format "elpa/%s" package))
           (lambda (dir) (cl-search package-search-string dir))
    (when package-dir

        (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 ()
  (if (equalp *current-theme-set* *coding-themes*)
      (setq *current-theme-set* *writing-themes*)
    (setq *current-theme-set* *coding-themes*))

(defun my-theme-string ()
  (if (car custom-enabled-themes)
      (format "%s is current" (car custom-enabled-themes))

(defun my-theme-cycler ()
  (let ((still-cycling t))
    (message (format "%s [n]ext or [p]revious. Anything else to quit."
    (while still-cycling
      (let ((char (read-key)))
         ((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."

(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)

(defun my-theme-command-next ()
  (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)

(defun my-theme-command-previous ()
  (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)

4.7.2 Installed Themes

(package-install 'autothemer) ;; for custom themes

(setq my-installed-themes

(dolist (package my-installed-themes)
  (when (not (package-installed-p package)) 
    (package-install package)))

4.7.3 Choice Themes

(setq *coding-themes*
        ;; light
        ;; medium
        ;; dark

(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)

5 Time Managment

(setq org-enforce-todo-dependencies t
      org-enforce-todo-checkbox-dependencies t)

(setq org-edit-src-content-indentation 0)

5.1 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.

(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)

5.2 CALFW calendar

(package-install 'calfw)
(package-install 'calfw-org)
(require 'calfw)
(require 'calfw-org)

   '("c" "Calendar" entry
     (file+headline "~/notes/deft/project-Planner.org" "CALENDAR")
     "* %?\n %(cfg:org-capture-day)")))

5.3 Org Refile

(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)))

5.4 Org Capture

(setq org-capture-templates
     ("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)"))))

5.5 Org Agenda

 '(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)))

6 Communication

6.1 ERC

(setq erc-hide-list '("JOIN" "QUIT" "PART"))

7 Reading, Notes, and Writing

7.1 General Reading Tools

wordnut is a wordnet interface

(package-install 'wordnut)

(def-my-command my-reading-command
  '((?l "[l]ookup word" wordnut-lookup-current-word)
    (?L "[L]ookup any word" wordnut-search)))

imenu-list displayes imenu results in a a navigable table-of-contents tree-like format.

(package-install 'imenu-list)

7.2 Calibre db

(package-install 'calibredb)

(require 'calibredb)
(setq calibredb-root-dir "~/Calibre")
(setq calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir))

7.3 PDF tools for Reading and Annotating PDFS

7.3.1 PDF Tools

(package-install 'pdf-tools)

7.3.2 Some functions to quickly annotate

(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

Return nil, if no annotation was found."
  (let (window)
    (when (posnp pos)
      (setq window (posn-window pos)
            pos (posn-object-x-y pos)))
      (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))

(defun my-pdf-annot-add-text-annotation ()
  (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)))

7.4 Nov

(package-install 'nov)
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

7.5 Elfeed for Reading RSS Feeds

(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")


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.

(load "~/notes/ps-ccrypt.el")

7.7 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.

(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)))

7.8 Deft

(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"))

7.9 Writeroom

(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)))

7.10 EWW config

(setq browse-url-browser-function 'eww-browse-url)

;; (add-hook 'eww-mode-hook
;;           (lambda ()
;;             (writeroom-mode t)))

7.11 Markdown Editing

(package-install 'markdown-mode)

7.12 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.

(defun my-freaking-align ()
  (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)))

7.12.1 My leader key Special inserts

Included are common greekletters, arrows, logical symbols and some math symbols.

(defun inserter (what)
  (lexical-let ((what what))
    (lambda ()
      (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 "∨"))))

8 Software Development

(show-paren-mode 1)
(which-function-mode 1)

8.1 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.

(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)

 '((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.")

8.2 Pair-Programming

8.2.1 CRDT for pair programming

(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)))

8.3 Tools Essential To Development

(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)

8.3.1 Projectile

(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)))

8.4 Shell Config

The following defines commands used by my leader key ssytem to association one shell with each perspective layout

(defun persp-shell--shell-name ()
  (format "*shell %s*" (persp-current-name)))

(defun persp-shell--shell-buffer-p (buffer)
  (string-equal (buffer-name buffer)

(defun persp-shell--shell ()
  (cl-find-if 'persp-shell--shell-buffer-p
              (persp-buffers (persp-curr))))

(defun persp-shell--jump-to-persp-shell ()
  (let ((buff (persp-shell--shell)))
    (if buff (switch-to-buffer-other-window buff)
      (shell (persp-shell--shell-name)))))

8.5 Common Lisp

8.5.1 Packages

(package-install 'paredit)
(package-install 'sly)

8.5.2 Sly

(def-my-command my-lisp-mode-command
  '((?d "[d]ocumentation" sly-describe-symbol)
    (?h "[h]yperspec" hyperspec-lookup)
    (?S "[S]ync package" sly-mrepl-sync)
    (?\t "TAB inpsect" sly-inspect)))

;; (defvar +symbols-in-cl+ 977)

;; (defun sky-random-words-of-encouragement ()
;;   "Return a string of hackerish encouragement."
;;   (sly-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)

(setq sly-compile-file-options
      (list :fasl-directory (slime-fasl-directory)))

;; (setq slime-compile-file-options
;;       (list :fasl-directory (slime-fasl-directory)))

8.5.3 Editing Config

(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

(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: ")
   (format +common-lisp-package-template+  name name)))

(with-eval-after-load 'lisp-mode
    (setq common-lisp-hyperspec-root "file:///home/colin/HyperSpec/")))

(setq lisp-lambda-list-keyword-parameter-alignment t
      lisp-lambda-list-keyword-alignment t)
(put 'make-instance 'common-lisp-indent-function 1)

8.5.4 Coalton

(setq +coalton-package-template+
(defpackage #:%s
   (#: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)



(defun insert-coalton-defpackage (name)
  (interactive "sName: ")
   (format +coalton-package-template+  name name)))


8.6 Haxe

(package-install 'haxe-mode)

9 Tools

9.1 Export Emacs Buffer

(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)))

9.2 Helpful

(package-install 'helpful)

10 External Loads

(load "~/.emacs.d/cicadas-config.el")
(load "~/projects/cicadas.org/cicatasks.el")

Created: 2024-05-11 Sat 12:58