aboutsummaryrefslogtreecommitdiff

Table of Contents

-- 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)
  (with-temp-buffer
    (insert-file-contents f)
    (buffer-string)))



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)
           (native-comp-available-p))
  (setq package-native-compile nil
        native-comp-always-compile nil))

1.2 Packages Setup Config

I'm using melpa and elpa package archives.

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

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
  '((?/ "[/] search buffer" swiper)
    (?? "[?] imenu" imenu-list)
    (?q "[q]uery 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]applications" my-utilities-command)
    (?t "[t]hemes" my-theme-cycler)
    (?T "toggle [T]heme set" toggle-theme-set)
    (?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)
    (?d "[d]ired" dired)
    ;(?d "[d]irvish" dirvish)
    (?r "[r]eading menu" my-reading-command)
    (?s "[s]lime selection" my-lisp-switch-command)
    (?h "[h]elp" helpful-at-point)))


(global-set-key (kbd "M-m") 'my-leader-command)

2.3 My leader Key Major Mode Menu

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

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

3 Org Mode Configs


3.1 Org Mode Main 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)))

3.2 My-Leader Key for Org Major Mode

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

3.3 Org Protocol Config

Following the guide here about setting up org protocol and emacs server.

This allows emacs to intercept org protocol requests from emacsclient in order to take some actions. I'm using it here as part of a DIY read-it-later app - I can push a button in my web browser and cache an article for later reading.

3.3.1 Org init.el config

First, update the config

(server-start)
(require 'org-protocol)

3.3.2 desktop entry

Second, make an org-protocol desktop entry

[Desktop Entry]
Name=org-protocol
Comment=Intercept calls from emacsclient to trigger custom actions
Categories=Other;
Keywords=org-protocol;
Icon=emacs
Type=Application
Exec=emacsclient -- %u
Terminal=false
StartupWMClass=Emacs
MimeType=x-scheme-handler/org-protocol;

and tell your system about it. You might need to install something:

sudo apt-get install desktop-file-utils

Then run this:

update-desktop-database ~/.local/share/applications/

Finally, to actually use it, make a book mark like so:

e.g. here's one for org capture

javascript:location.href='org-protocol://capture:/w/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())

3.4 Bells and Whistles

(package-install 'org-superstar)
(require 'org-superstar)
(add-hook 'org-mode-hook (lambda ()
                           (org-superstar-mode 1)
                           (visual-line-mode)))

4 UI

4.1 Fonts

(add-to-list 'default-frame-alist
             '(font . "Comic Mono-12")
             ;'(font . "Victor Mono-10")
             )


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

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

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

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)
(window-numbering-mode)

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

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 'diminish)
;; (require 'diminish)
;; ;(diminish 'company-mode)
;; ;(diminish 'paredit-mode)
;; ;(diminish 'projectile-mode)
;; (diminish 'ivy-mode)
;; (diminish 'org-src-mode)
;; (diminish 'eldoc-mode)
;; (diminish 'beacon-mode)
;; (diminish 'visual-line-mode)
;; (diminish 'org-auto-tangle-mode)
;; (diminish 'abbrev-mode)

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


4.7 Themes

4.7.1 Installed Themes

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

(setq my-installed-themes
      '(yoshi-theme leuven-theme zweilight-theme cybercafe-theme seoul256-theme))


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

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

4.7.3 Choice Themes

(setq *coding-themes*
      (append '(leuven seoul256 yoshi leuven-dark zweilight cybercafe)))

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

(custom-set-variables
 '(cfw:org-capture-template
   '("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
   (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)"))))

5.5 Org Agenda

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

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)
(pdf-tools-install)

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

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://www.n16f.net/blog/index.xml"                                     blog         programming  emacs  lisp)
        ("https://deprogrammaticaipsum.com/rss"                                    programming  blog)
        ("https://www.okdoomer.io/latest/rss"                                      blog         rant         sus)
        ("https://abuseofnotation.github.io/feed"                                  blog         philosophy   programming)
        ("https://whhone.com/index.xml"                                            blog         emacs)
        ("https://feedly.com/i/subscription/feed/https://www.cold-takes.com/rss/"  blog         )
        ("https://www.construction-physics.com/feed"                               science      blog)
        ("https://economicsfromthetopdown.com/feed"                                blog         economics    science)
        ("https://newsletter.aworkinglibrary.com/rss"                              culture      technology)
        ("https://harpers.org/feed"                                                culture      politics     news)
        ("https://solar.lowtechmagazine.com/posts/index.xml"                       technology)
        ("https://lambdaland.org/index.xml"                                        blog         lisp         emacs)
        ("https://warandpeas.com/feed"                                             comics)
        ("http://planet.lisp.org/rss20.xml"                                        lisp         blog)
        ("https://feeds.feedburner.com:443/dailykos/zyrjlhwgaef"                   politics     news)
        ("http://feeds2.feedburner.com/NoTechMagazine"                             technology)
        ("http://www.thingsmagazine.net/feed"                                      art          culture)
        ("https://commonstransition.org/feed/"                                     commons      p2p)
        ("http://blog.p2pfoundation.net/feed/"                                     p2p          activism     research)
        ("https://www.noemamag.com/feed"                                           culture      technology)
        ("https://theconvivialsociety.substack.com/feed"                           technology   culture      philosophy)
        ("https://daily.jstor.org/feed"                                            news)
        ("https://www.merriam-webster.com/wotd/feed/rss2"                          wordoday)
        ("https://www.viruscomix.com/rss.xml"                                      comics)
        ("https://smbc-comics.com/rss.php"                                         comics)
        ("https://www.science.org/blogs/pipeline/feed"                             science      news)
        ("https://existentialcomics.com/rss.xml"                                   comics)
        ("http://feeds.feedburner.com/OddityCentral"                               weird)
        ("https://journal.stuffwithstuff.com/rss.xml"                              programming  blog)
        ("https://rss.slashdot.org/Slashdot/slashdotMain"                          tech         news)))      


(setq-default elfeed-search-filter "@2-weeks-ago +unread")

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

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

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

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)

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



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

;; see https://github.com/magit/magit/issues/5011
(require 'seq-25)

(package-install 'paredit)
(package-install 'ag)
(package-install 'lice)


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.3.2 Company

;(package-install 'company)

                                        ;(add-hook 'after-init-hook 'global-company-mode)



;; (setq company-frontends
;;       '(company-pseudo-tooltip-unless-just-one-frontend
;;         company-echo-metadata-frontend
;;         company-preview-frontend)
;;       company-auto-complete t)

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

8.5 Common Lisp

8.5.1 Packages

(package-install 'paredit)
(package-install 'slime)
;(package-install 'slime-company)






8.5.2 Starting SLIME with different Lisps

(defvar my-current-slime-name "sbcl")
(setq sbcl-command "/home/colin/bin/sbcl --dynamic-space-size 4096")
(setq inferior-lisp-program sbcl-command)

(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 sbcl-command "sbcl"))
    (?e "[e]cl" ,(start-slime-with "ecl" "ecl"))
    (?a "[a]bcl" ,(start-slime-with "abcl" "abcl"))
    ;(?c "[c]cl" ,(start-slime-with "~/lisp/ccl/lx86cl64" "ccl"))
    ))



8.5.3 Lisp Mode Leader Key command

Requires installation of the hyperspec and cltl packages on debain from debian contrib

sudo apt install cltl hyperspec
(defun common-lisp-quickdocs-lookup ()
  (interactive)
  (let ((package-name (delete ?: (format "%s" (symbol-at-point)))))
    (eww (format "https://quickdocs.org/%s" package-name))))

(defun common-lisp-quickdocs-search (term)
  (interactive "sTerm: ")
  (eww (format "https://quickdocs.org/-/search?%s"
               (url-build-query-string (list (list "q" term))))))

(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)
    (?s "[s]ymbol describe" slime-describe-symbol)
    (?S "[S]ync package" slime-sync-package-and-default-directory)
    (?d "[d]ocumentation" slime-documentation)
    (?\t "[TAB] inspect-presentation" slime-inspect-presentation-at-point)
    (?B "Open CLTL2 [B]ook" open-cltl2)
    (?q "[q]ickdocs lookup" common-lisp-quickdocs-lookup)
    (?Q "[Q]uickdocs Query" common-lisp-quickdocs-search)
    (?b "[b]rows system" slime-browse-system)
    (?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:///home/colin/HyperSpec/")))



8.5.4 Editing Config

(slime-setup '(slime-fancy ; slime-company
               slime-fuzzy ; slime-asdf
               ))

;; (setq slime-company-completion 'fuzzy
;;       slime-company-after-completion 'slime-company-just-one-space)

(package-install 'ac-slime)
(require 'ac-slime)
(add-hook 'slime-mode-hook 'set-up-slime-ac)
(add-hook 'slime-repl-mode-hook 'set-up-slime-ac)
(eval-after-load "auto-complete"
  '(add-to-list 'ac-modes 'slime-repl-mode 'lisp-mode))


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

;; The default imenu matcher is defined in the variable
;; lisp-imenu-generic-expression as part of lisp-mode.el.  I extend
;; that definition here to treat anything that begins with ="def"= as
;; a match.



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


8.5.5 SLIME-TWEAKS

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

8.5.6 LISP-MODE tweaks


8.5.7 Coalton


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

(message "HERE HERE HERE")

insert-coalton-defpackage

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 Tangle

This block of code tangles the above into ~/.emacs.d/init.el which emacs loads at startup.

;;;; init.el 

;;;; DO NOT EDIT: This file has been generated by org-babel-tangle
;;;; from a source file called init-el.org.

<<preamble>>
<<native-comp>>
<<packages-setup-config>>


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LEADER KEY DEFINITION AND TOPLEVEL MENUS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


<<my-leader-key-system>>
<<my-leader-key-toplevel-menu>>
<<my-leader-key-major-mode-menu>>
<<my-leader-key-applications-menu>>
<<my-leader-special-edit>>
<<my-special-inserts>>

;;;;;;;;;;;;;;;;;;;;;;
;; ORG-MODE CONFIGS ;;
;;;;;;;;;;;;;;;;;;;;;;

<<org-mode-main-config>>
<<org-mode-leader-key-menu>>
<<org-protocol-config>> 
<<org-bells-and-wistles>>

;;;;;;;;
;; UI ;;
;;;;;;;;

<<ui-chrome-config>>
<<ui-tweaks-config>>
<<ui-fonts-config>>

<<ui-completion-engine>>
<<ui-windows-and-perspectives-packages>>
<<ui-window-leader-key-menu>>
<<ui-buffer-leader-key-menu>>
<<ui-perspectives-leader-key-menu>>
<<modeline-config>>

<<ui-themes-installed>>
<<ui-themes-theme-switcher>>
<<ui-themes-choice-themes>>
<<ui-org-mode-tweaks>>
<<ui-fonts>>

;;;;;;;;;;;;;;;;;;;;;
;; TIME MANAGEMENT ;;
;;;;;;;;;;;;;;;;;;;;;

<<time-management-preamble>>
<<pomidor>>
<<calfw-org-config>>
<<org-refile-config>>
<<org-capture-config>>
<<org-agenda-config>>

;;;;;;;;;;;;;;;;;;;;;;;;;
;; COMMUNICATION TOOLS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;

<<erc-config>>


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; READING, WRITING, AND NOTETAKING ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

<<general-reading-tools>>
<<calibre-config>>
<<pdf-tools>>
<<pdf-mode-config>>
<<nov>>
<<elfeed-config>>
<<ccrypt>>
<<toggler>>
<<deft>>
<<writeroom>>
<<eww-config>>
<<markdown-editing>>

;;;;;;;;;;;;;;;;;;
;; SOFTWARE DEV ;;
;;;;;;;;;;;;;;;;;;

<<software-development-preamble>>
<<literate-programming>>
<<crdt-config>>
<<software-dev-essentials>>
<<projectile>>
<<company>>
<<shell-config>>

<<common-lisp-packages>>

<<common-lisp-switch-commands>>

<<common-lisp-mode-command>>

<<common-lisp-editing-config>>

<<slime-tweaks>>

<<coalton-config>>

<<haxe-config>>

;;;;;;;;;;;;;;;;;;;;;;
;; TOOLS AND UTILS  ;;
;;;;;;;;;;;;;;;;;;;;;;

<<buffer-export-config>>
<<helpful>>

Created: 2023-12-01 Fri 22:23

Validate