Table of Contents

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.

;;;; init.el 

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

(setq custom-file (concat user-emacs-directory "custom.el"))
(load custom-file 'noerror)

(setq warning-minimum-level :emergency)


;;; utilities
(defun read-file-into-string (f)
    (insert-file-contents f)


1.1 Native Compilation

New in emacs 28, native compilation can be enabled:

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

(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 emulates menus. An initial key (M-m for me) opens the top level menu. The menu presents a key to press that either leads to the next menu or run a specific interative function.

It all starts with the def-my-command macro, which associates a key to a menu of commands. Each 'command' is just an interactive function.

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 inital 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)
    (?q "[q]uery replace" query-replace)
    (?i "[i]nsert" my-special-insert)
    (?' "['] 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]irvish" dirvish)
    (?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)
        ;(zettel-mode my-zettel-mode-command)
        (slime-repl-mode my-lisp-mode-command)
        (pdf-view-mode my-pdf-view-mod-command)
        (lisp-mode my-lisp-mode-command)))

(defun my-major-mode-command ()
  (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-readonly) 
    (?p "[p]omodoro" pomidor)
    (?w "[w]eb browser (eww)" eww)
    (?C "[C]RDT" my-crdt-commands)))

2.5 My leader key Special inserts

(defun inserter (what)
  (lexical-let ((what what))
    (lambda ()
      (insert what))))

(def-my-command my-special-insert
  `((?l "[l] λ" ,(inserter "λ"))))

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

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

(defvar +cicadas-surf-task-status-file+ "/ssh:colin@cicadas.surf:~/.task")

(defun clock-in-external-log-advice (&rest args)
  "to be added as advice to org-clock-in"
  (when +cicadas-surf-task-status-file+
      (insert "👷 ")
         (buffer-name (marker-buffer org-clock-marker))
      (insert " -- ")
      (insert org-clock-heading)
      (insert " 👷")
      (write-file +cicadas-surf-task-status-file+))))

(defun clock-out-external-log-advice (&rest args) 
  (when +cicadas-surf-task-status-file+
      (write-file +cicadas-surf-task-status-file+))))

(advice-add 'org-clock-in :after #'clock-in-external-log-advice)
(advice-add 'org-clock-out :after #'clock-out-external-log-advice)

3.2 Org Mode and Babel Configuration

 '((emacs-lisp . t)
   (python . t)
   (lisp . t)
   (C . t)
   (shell . t)))

3.3 My-Leader Key for Org Major Mode

(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.4 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.4.1 Org init.el config

First, update the config

(require 'org-protocol)

3.4.2 desktop entry

Second, make an org-protocol desktop entry

[Desktop Entry]
Comment=Intercept calls from emacsclient to trigger custom actions
Exec=emacsclient -- %u

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


4 UI

;;; 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 Modeline Config

;; (package-install 'doom-modeline)
;; (require 'doom-modeline)
;; (doom-modeline-mode 1)

4.4 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.5 Bells and Whistles

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

4.6 My Leader Keys

4.7 Completions Engine

(package-install 'ivy)
(package-install 'smex)
(package-install 'swiper)
(ivy-mode 1)
(setq ivy-use-selectable-prompt t)
(global-set-key (kbd "M-x") 'smex)

4.8 Buffers, Windows, and Perspectives


4.8.1 Packages

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

(package-install 'rotate)

(package-install 'window-numbering)

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

4.8.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.8.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.8.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.9 Themes


4.9.1 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.9.2 Theme Switcher

(setq *coding-themes*

(setq *writing-themes*

(setq *current-theme-set* *coding-themes*)

(defun toggle-theme-set ()
  (if (equalp *current-theme-set* *coding-themes*)
      (setq *current-theme-set* *writing-themes*)
    (setq *current-theme-set* *coding-themes*))

(when (car custom-enabled-themes)
  (disable-theme (car custom-enabled-themes)))

(load-theme (first *current-theme-set*) t)

(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]evious. 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]evious. Anything else to quit."

(defun my-theme-linum-mode-cycler ()
  "sometimes cycling themes when linum mode is on causes screwy display. cycling helps."
  (when (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)

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.

#:name: pomidor

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

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" entry
      (file+olp+datetree "~/notes/deft/Web.org" "Weblink")
      "* TOREAD %:annotation \n\n %i\n\n")
     ("i" "Inbox" entry
      (file+headline "~/notes/deft/project-Planner.org" "INBOX")
     ("j" "Journal" entry
      (file+olp+datetree "~/notes/circadian.org.cpt")
     ("c" "Calendar" entry
      (file+headline "~/notes/deft/project-Planner.org" "CALENDAR")
      "* %?\n %(cfw:org-capture-day)"))))

;; ("i" "Inbox" entry
;;       (file "~/notes/deft/project-Inbox.org")
;;       "")

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

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

7 Reading, Notes, and Writing



7.1 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.2 PDF tools for Reading and Annotating PDFS

7.2.1 PDF Tools

(package-install 'pdf-tools)

7.2.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.3 Nov

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

7.4 Elfeed for Reading RSS Feeds

(package-install 'elfeed)

(require 'elfeed)

(setq elfeed-feeds
      '(("https://harpers.org/feed" culture politics news)
        ("https://solar.lowtechmagazine.com/posts/index.xml" technology)
        ("http://feeds.feedburner.com/FutilityCloset" art culture)
        ("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.viruscomix.com/rss.xml" comics)
        ("https://smbc-comics.com/rss.php" comics)
        ("https://existentialcomics.com/rss.xml" comics)
        ("https://journal.stuffwithstuff.com/rss.xml" programming blog)
        ("https://rss.slashdot.org/Slashdot/slashdotMain" tech news)))

(setq-default elfeed-search-filter "@1-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.6 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")

(defun toggle-secrets-readonly ()
  (when (equal (buffer-name) "secrets.org.cpt")

7.7 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.8 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.9 EWW config

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

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

7.10 Markdown Editing

(package-install 'markdown-mode)

8 Software Development

(show-paren-mode 1)







8.1 Literate Programming

Hacks and tweaks for literate programming. Org auto tangle will tangle a file whenever it is saved.

(package-install 'org-auto-tangle)

(require 'org-auto-tangle)
(add-hook 'org-mode-hook 'org-auto-tangle-mode)

8.2 Pair-Programming


8.2.1 CRDT for pair programming

(package-install 'crdt)

8.3 Tools Essential To Development

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

8.4 Shell Config

The following defines commands used by my leader key system to association one shell with each perspective aka 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 'slime)
(package-install 'slime-company)

(setq slime-contribs
      '(slime-fancy slime-company slime-fuzzy slime-asdf))

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 ()
    (setq inferior-lisp-program ,str)
    (setq my-current-slime-name ,name)

(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 ()
  (let ((buff (slime-in-this-layout-p my-current-slime-name)))
    (if buff (switch-to-buffer-other-window buff)

(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
(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)
    (?b "[b]rows system" slime-browse-system)
    (?h "[h]yperspec lookup" hyperspec-lookup)))

(defun open-cltl2 ()
  (eww "file:///usr/share/doc/cltl/clm/clm.html"))

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

8.5.4 Editing Config

(slime-setup '(slime-fancy slime-company))

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

(autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t)
(add-hook 'emacs-lisp-mode-hook       #'enable-paredit-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)
(add-hook 'lisp-mode-hook             #'enable-paredit-mode)
(add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode)
(add-hook 'scheme-mode-hook           #'enable-paredit-mode)
(add-hook 'clojure-mode-hook          #'paredit-mode)

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


(defvar +symbols-in-cl+ 977)

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

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

(message "HERE HERE HERE")


8.6 Haxe

(package-install 'haxe-mode)

9 Tools


9.1 Dirvish

Dirvish is a slicker dired - i.e it's a file manager.

(package-install 'dirvish)

9.2 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.3 Helpful

(package-install 'helpful)

Created: 2023-08-19 Sat 09:41