Theresa O’Connor

Building a habitable computing environment

Share and Enjoy!〉=
 ___  _  _   __   ___   ___     __   _  _  ___     ___  _  _    __  __  _  _  _
/ __)( )( ) (  ) (  ,) (  _)   (  ) ( \( )(   \   (  _)( \( )  (  )/  \( \/ )/ \
\__ \ )__(  /__\  )  \  ) _)   /__\  )  (  ) ) )   ) _) )  (  __)(( () )\  / \_/
(___/(_)(_)(_)(_)(_)\_)(___)  (_)(_)(_)\_)(___/   (___)(_)\_)(___/ \__/(__/  (_)

Introduction

Hi, I'm Tess.

I've been using computers for a very long time, and many of my configuration files have been around, in one form or another, for over twenty years. Many years ago, I often found myself making related changes to multiple dotfiles. It occurred to me that it might be easier to understand my configuration if I wrote it as a literate program. I believe history has demonstrated how very wrong I was, but I'm too lazy to undo the damage at this point. All of my dotfiles are interleaved in one very long literate program, and for some reason you're reading it now. I'm sorry.

Table of Contents

Concepts

The Allure of Love〉=
“Someone who does not run
  toward the allure of love
    walks a road where nothing lives.”
        — Rumi

$SYSNAME

In college we used AFS for a campus-wide network filesystem, so my home directory was shared across machines running different kinds of Unix on different kind of CPUs. I often have a bin/ directory in my home directory that has scripts and binaries in it, but how do you handle the case where you want to put binaries built for several different kinds of machines in your PATH?

AFS had this feature where you can use a special symbol, @sys, in a file path, and that will be replaced with a concise description of the architecture and OS of the machine you're on. It's similar to GNU's buildtype, but a bit simpler. So you simply add ~/@sys/bin to your PATH, make architecture-and-os-specific directories for your binaries, and AFS will do the right thing.

Anyway, I haven't used AFS in a long, long time, but I'm still in the habit of putting arch/OS specific binaries in directories like this. Lacking @sys, I emulate the feature with the environment variable $SYSNAME.

Here's how I set $SYSNAME in Zsh, PowerShell, and Emacs:

Configure SYSNAME in Zsh〉=
# I put architecture-specific local binaries I've built in ~/$SYSNAME/bin.
MACHTYPE=`uname -m`
OSTYPE=`uname -s`
export SYSNAME=`echo ${MACHTYPE}-${OSTYPE} | tr '[:upper:]' '[:lower:]'`

Configure SYSNAME in PowerShell〉=
# SYSNAME
if ($null -eq $Env:SYSNAME) {
    if ($IsWindows) {
        $Env:SYSNAME=$($Env:PROCESSOR_ARCHITECTURE,$Env:OS -join '-').ToLower()
    } else {
        $Env:SYSNAME= ($(uname -m),$(uname -s) -join '-').ToLower()
    }
}
Configure SYSNAME in Emacs〉=
(defconst tess-sysname
  (if (eq system-type 'windows-nt)
      (downcase (format "%s-%s"
                        (getenv "PROCESSOR_ARCHITECTURE")
                        (getenv "OS")))
    (replace-regexp-in-string "-\(pc\|unknown\)-linux-gnu" "-linux"
      (replace-regexp-in-string "arm-apple" "arm64" system-configuration)))
  "What kind of OS are we running on.")

Home sweet home

Mercy, Moderation, and Modesty〉=
我有三寶持而保之  I have three treasures.
                  I keep and treasure them.
一曰慈            The first, mercy,
二曰儉            The second, moderation,
三曰不敢為天下先  The third, modesty.
    — 老子        (trans. Ursula K. Le Guin)
What are they to me?〉=
銀も              What are they to me,
金も玉も          Silver, or gold, or jewels?
何せむに          How could they ever
まされる宝        Equal the greater treasure
子にしかめやも    That is a child? They can not.
    — 山上憶良    (trans. Edwin Cranston)

bin/ - shell scripts

This directory should be in my shell's search path as well as Emacs'.

Guard against adding duplicate entries to either fpath or path

Don't add duplicate entries to path or fpath〉=
typeset -U fpath path

This add-to-path function prepends each directory passed to it to $path iff the dir exists.

Setting PATH in Zsh〉=
add-to-path() {
    emulate -L zsh
    local dir
    local -i added=1
    for dir in $*; do
        if [[ -d $dir ]]; then
            path=($dir $path)
            added=0
        fi
    done
    return $added
}

And here's more or less the same thing in PowerShell.

Setting PATH in PowerShell〉=
<#
.SYNOPSIS

Add-PathsToEnvPATH adds the given paths to $Env:PATH iff they exist and are directories. #> function Add-PathsToEnvPATH { param([string[]]$paths) begin { $additions = '' } process { if ((-not ([string]::IsNullOrEmpty($))) -and (Test-Path -Path $ -PathType Container)) { $additions += [IO.Path]::PathSeparator + $_ } } end { if ($PSBoundParameters.ContainsKey('paths')) { foreach ($path in $paths) { if ((-not ([string]::IsNullOrEmpty($path))) -and (Test-Path -Path $path -PathType Container)) { $additions += [IO.Path]::PathSeparator + $path } } } $Env:PATH += $additions } }

At the end of my PowerShell config file, I try to clean up the mess that is Windows' $PATH environment variable.

Clean up PowerShell's PATH〉=
# Remove empty, duplicate, and missing PATH entries.
$PathArray = $Env:PATH -split [IO.Path]::PathSeparator |
    Where-Object { '' -ne $_} | Sort-Object -Unique |
    Where-Object { Resolve-Path $_ -ErrorAction SilentlyContinue } |
    Sort-Object -Descending -Property Length

$Env:PATH = $PathArray -join [IO.Path]::PathSeparator

Remove-Variable 'PathArray'

Here are a bunch of predicates that check what kind of command something is and if it's available.

Wrappers around whence to make my zsh config more readable〉=
command-recognized() {
    emulate -L zsh
    whence $1 > /dev/null
}

Temporary alias until I track down all my uses of the old name

alias is-in-path=command-recognized

command-not-recognized() { [[ whence -w $1 = "$1: none" ]] }

command-in-path() { [[ whence -w $1 = "$1: command" ]] }

is-alias() { [[ whence -w $1 = "$1: alias" ]] }

is-builtin() { [[ whence -w $1 = "$1: builtin" ]] }

is-function() { [[ whence -w $1 = "$1: function" ]] }

is-reserved-word() { [[ whence -w $1 = "$1: reserved" ]] }

Setting PATH in Zsh〉=
add-to-path ~/bin

Ensure HOME/bin is in exec-path〉=
(add-to-list 'exec-path (expand-file-name "~/bin/"))

Tell Zsh where to look for function definitions〉=
mkdir -p $XDG_DATA_HOME/zsh/functions

fpath=($XDG_DATA_HOME/zsh/functions $fpath)

ip

ip simply prints the current IP address.

ip in Zsh〉=
default-ifaces() {
    emulate -L zsh

IPCMD=`whence -p ip 2> /dev/null`
if (( $? == 0 )); then
    $IPCMD route | grep default | sed -e 's/^none //g'| awk '{ print $5 }'
    return $?
fi

local default='default'
local iface_field='4'
if [[ `uname -s` = 'Linux' ]]; then
    default='^0.0.0.0'
    iface_field='8'
fi

if command-recognized netstat; then
    netstat -rn | grep $default | grep -v utun | awk "{ print \$${iface_field} }"
else
    print "$0: 'netstat' not found" >& 2
    return 1
fi

}

ip() { emulate -L zsh

local interfaces=$1
if [[ -z $interfaces ]]; then
    interfaces=`default-ifaces`
    if (( $? != 0 )); then
        return 1
    fi
fi

typeset -a ARGS
CMD=`whence -p ip 2> /dev/null`

if (( $? == 0 )); then
    ARGS=(addr show dev)
elif [[ -x /sbin/ifconfig ]]; then
    CMD='/sbin/ifconfig'
    ARGS=()
else
    print "Don't know how to find out the IP address." >& 2
    return 1
fi

for IFACE in ${=interfaces}; do
    $CMD $ARGS $IFACE | grep inet | grep -v inet6 | awk '{print $2}' | sed -e 's/\/[[:digit:]][[:digit:]]//'
done

}

ip in PowerShell〉=
function ip {
    (Get-NetIPAddress | ? { $_.PrefixOrigin -ne 'WellKnown' }).IPAddress
}
defun tess-ip〉=
(defvar tess-default-network-interface
  (cond
    ((eq system-type 'darwin) "en0")
    ((eq system-type 'gnu/linux) "eth0")
    (t nil)))

(defun tess-ip (&optional interface) (interactive (list (completing-read "Interface: " (mapcar 'car (network-interface-list)) nil t nil nil tess-default-network-interface))) (let ((addresses (mapcar (lambda (entry) (let ((formatted (substring (format-network-address (cdr entry)) 0 -2))) formatted)) (if (not interface) (network-interface-list) (list (assoc interface (network-interface-list))))))) ;; Only return a list of addresses when there's more than one. (if (not (cdr addresses)) (car addresses) addresses)))

(defun eshell/ip (&rest arguments) (let ((addresses (apply 'tess-ip arguments))) (if (stringp addresses) addresses (mapconcat 'identity addresses "\n"))))

dr

This prints the default route.

dr in Zsh〉=
dr() {
    emulate -L zsh

IPCMD=`whence -p ip 2> /dev/null`
if (( $? == 0 )); then
    $IPCMD route | grep default | sed -e 's/^none //g'| awk '{ print $3 }'
    return $?
fi

local default='default'
if [[ `uname -s` = 'Linux' ]]; then
    default='^0.0.0.0'
fi
if command-recognized netstat; then
    netstat -rn | grep $default | grep -v utun | awk '{print $2}'
else
    print "$0: 'netstat' not found" >& 2
    return 1
fi

}

dr in PowerShell〉=
function dr {
    (Get-NetRoute | ? { $_.DestinationPrefix -eq '0.0.0.0/0' }).NextHop
}

ssid

What's the SSID of this Wi-Fi network?

ssid in Zsh〉=
ssid() {
    emulate -L zsh

if ! command-recognized networksetup; then
    print "Dunno how to ssid on `uname -s`." >& 2
    return 1
fi

local IFACE='unknown'
local IFS='

' local PARSE_THIS_LINE=false for line in networksetup -listallhardwareports; do if $PARSE_THIS_LINE; then IFACE=echo "${line}" | cut -c 9- break fi if [[ 'Hardware Port: Wi-Fi' = "${line}" ]]; then PARSE_THIS_LINE=true fi done networksetup -getairportnetwork $IFACE | grep '^Current Wi-Fi Network' | cut -c 24- }

ssid in PowerShell〉=
function ssid {
    (Get-NetConnectionProfile | ? { $_.InterfaceAlias -eq 'Wi-Fi' }).Name
}

Common utilities

All of the above scripts share these implementation bits:

Default interface name on macOS〉=
netstat -rn | grep default | grep -v utun | awk '{ print $4 }'
Default interface name on FreeBSD〉=
netstat -rn | grep default | cut -c 65-

code/ - git repositories

define tess-code-dir〉=
(defconst tess-code-dir "~/code"
  "Where I check out version-controlled things.")
ninja-mode〉=
(when (locate-library "ninja-mode")
  (autoload 'ninja-mode "ninja-mode" nil t)
  (add-to-list 'auto-mode-alist '("\\.ninja\\'" . ninja-mode)))

code/Makefile

code/Makefile〉=
# I've only tested this Makefile with GNU Make. -*- makefile-gmake -*-

ifeq ($(shell uname -s),Darwin) EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs -q --no-site-file else EMACS=emacs -q --no-site-file endif

CWD=~/code

37emacs clone rule〉 〈erc clone rule〉 〈gnus clone rule〉 〈github elisp make rules〉 〈Generic el-to-elc Make rule

37emacs clone rule〉=
37emacs/backpack.el:
        git clone git@github.com:hober/37emacs.git

erc clone rule〉=
erc/erc.el:
        git clone ssh://hober@git.sv.gnu.org/srv/git/erc.git

elisp/ - Emacs Lisp libraries

define tess-elisp-dirs and tess-elisp-dir〉=
(defconst tess-elisp-dirs
  (mapcar (lambda (entry)
            (let ((name (car entry))
                  (default-dir (cdr entry)))
              (if default-dir
                  (expand-file-name name default-dir)
                nil)))
          (list (cons "emacs" (xdg-config-home))
                (cons ".emacs.d" (xdg-config-home))
                (cons "elisp" tess-mac-shared-home)
                (cons "elisp" tess-mac-data-volume)
                (cons "elisp" "~"))))

(defconst tess-elisp-dir (or (catch 'found (mapc (lambda (dir) (when (and (stringp dir) (file-directory-p dir)) (throw 'found dir))) tess-elisp-dirs)) "~/elisp") "Where I keep local copies of elisp files, both my own and others'.")

Configure load-path〉=
(mapc (lambda (dir)
        (when (and (stringp dir) (file-directory-p dir))
          (add-to-list 'load-path dir)
          (let ((default-directory dir))
            (load "./subdirs.el" t))))
      tess-elisp-dirs)

elisp/subdirs.el〉=
(cond ((fboundp 'normal-top-level-add-subdirs-to-load-path)
       (normal-top-level-add-subdirs-to-load-path))
      ((fboundp 'paths-find-recursive-load-path)
       (let ((subdirs (paths-find-recursive-load-path
                       (list default-directory))))
         (setq load-path (nconc subdirs load-path)))))

elisp/Makefile

byte-compile command〉=
byte-compile() {
    emulate -L zsh
    emacs -batch -L . -f batch-byte-compile $*
}

_byte-compile() { emulate -L zsh _arguments ':file:_files -g "*.el"' } compdef _byte-compile byte-compile

elisp/Makefile〉=
# Rules for fetching and byte-compiling elisp libraries. -- makefile-gmake --

ifeq ($(shell uname -s),Darwin) EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs -q --no-site-file else EMACS=emacs -q --no-site-file endif

usage: @echo "usage: make [foo.el | foo.elc | autoloads | usage | all]" @echo " make foo.el will fetch foo.el from the Internet" @echo " make foo.elc will byte-compile foo.el." @echo " (fetching foo.el first if necessary)." @echo " make all will turn buil .elc for all .el in this dir." @echo " make autoloads will update the autoloads file." @echo " make usage displays this message." @echo

autoloads make rule

ELS = $(shell ls -1 *.el) ELCS = $(ELS:.el=.elc) all: $(ELCS) make $(ELCS)

elisp/Makefile〉=
Generic el-to-elc Make rule

Generic el-to-elc Make rule〉=
.el.elc:
        $(EMACS) -batch -L . 
-eval "(setq max-lisp-eval-depth 〈max-lisp-eval-depth〉)"
-eval "(setq max-specpdl-size 〈max-specpdl-size〉)"
-eval "(mapc (lambda (dir) (add-to-list 'load-path dir))
(parse-colon-path (getenv "LOAD_PATH")))"
-f batch-byte-compile $*.el

elisp/Makefile〉=
EMACSWIKI_DOWNLOAD=https://www.emacswiki.org/emacs/download/
GITHUB=https://raw.githubusercontent.com

Where I most recently fetched various random elisp files written by

other people.

applescript-mode.el fetch rule〉 〈boxquote.el fetch rule〉 〈color-theme fetch rules〉 〈css-mode.el fetch rule〉 〈csv.el fetch rule〉 〈deft.el fetch rule〉 〈dom.el fetch rule〉 〈ecmascript-mode.el fetch rule〉 〈erc-highlight-nicknames.el fetch rule〉 〈erc-robot.el fetch rule〉 〈espresso.el fetch rule〉 〈fillcode.el fetch rule〉 〈haskell-mode fetch fules〉 〈http-FOO.el fetch rules〉 〈http-twiddle.el fetch rule〉 〈install.el fetch rule〉 〈javascript.el fetch rule〉 〈mb-depth fetch rule〉 〈moz.el fetch rule〉 〈multi-region.el fetch rule〉 〈mwe-log-commands.el fetch rule〉 〈oddmuse.el fetch rule〉 〈paredit.el fetch rule〉 〈parenface.el fetch rule〉 〈psvn.el fetch rule〉 〈rpm-spec-mode.el fetch rule〉 〈ruby fetch rules〉 〈setnu.el fetch rule〉 〈swift major mode fetch rules〉 〈tc.el fetch rule〉 〈tidy.el fetch rule〉 〈tracking.el fetch rule〉 〈twit.el fetch rule〉 〈two-mode-mode.el fetch rule〉 〈wikipedia elisp fetch rules〉 〈vc-svn.el fetch rule〉 〈wdired.el fetch rule〉 〈xterm-frobs.el fetch rule

$SYSNAME/bin - binaries

Add ~/SYSNAME/bin to PATH〉=
add-to-path ~/$SYSNAME/bin ~/$SYSNAME/sbin

Add SYSNAME/bin to exec-path〉=
(add-to-list 'exec-path
             (expand-file-name "bin"
                               (expand-file-name tess-sysname "~")))

Setting PATH in PowerShell〉=
<#
.SYNOPSIS

Join-Paths makes it easier to call Join-Path on lots of arguments.

.DESCRIPTION

Join-Path only takes two arguments. But sometimes you want to bang a bunch of strings together to build a longer path. That's where Join-Paths comes in. #> function Join-Paths { param( [Parameter(Mandatory,ValueFromRemainingArguments)] [ValidateNotNullOrEmpty()] [string[]]$paths ) $joined, $unjoined = $paths foreach ($path in $unjoined) { $joined = Join-Path $joined $path } $joined }

Setting PATH in PowerShell〉=
(Join-Paths $Home bin),(Join-Paths $Home $Env:SYSNAME bin) |
  Add-PathsToEnvPATH

WSL: Ensure runemacs.exe is in PATH〉=
if (( $+WSLENV )); then
    add-to-path '/mnt/c/Program Files/Emacs/x86_64/bin'
fi

Emacs (PowerShell)〉=
if ($IsWindows) {
    Join-Paths ${Env:ProgramFiles} 'Emacs' 'emacs-*' 'bin' |
      Resolve-Path | Select-Object -Last 1 | Add-PathsToEnvPATH

if (Get-Command runemacs 2> $null) {
    Set-Alias -Name emacs -Value runemacs
    〈<a href='#emacsclient-powershell'>emacsclient (PowerShell)</a>〉
}

} elseif ($IsMacOS) { $slash = [IO.Path]::DirectorySeparatorChar

Join-Paths $slash Applications Emacs.app Contents MacOS bin | Add-PathsToEnvPATH

function emacs {
    $emacs = Join-Paths $slash Applications Emacs.app Contents MacOS Emacs
    & $emacs -nw @args
}

} 〈Use Emacs' quickurls from PowerShell

insert/ - skeleton files of various types

Configure auto-insert-mode〉=
(when (fboundp 'auto-insert-mode)
  (auto-insert-mode 1)
  (setq auto-insert-query nil)
  〈atom template〉
  〈css template〉
  〈html template〉
  〈js template〉
  〈latex template〉
  〈python template〉
  〈zsh template〉)

Local config files and XDG

I put local (machine-specific) config files in XDG Base Directory-style config directories. Only some systems come with XDG environment variables set, so I need to set them myself when they're missing.

XDG desktop files alternate extension〉=
(add-to-list 'auto-mode-alist '("\\.url\\'" . conf-desktop-mode))

Configure XDG_CONFIG_HOME and XDG_DATA_HOME〉=
: ${XDG_CONFIG_HOME:=/.config} ; export XDG_CONFIG_HOME
: ${XDG_DATA_HOME:=/.local/share}; export XDG_DATA_HOME
Configure XDG〉=
mkdir -p ${XDG_CONFIG_HOME} # set and exported in .zshenv
mkdir -p ${XDG_DATA_HOME}   # ditto
mkdir -p ${XDG_CACHE_HOME:=/.cache}; export XDG_CACHE_HOME
: ${XDG_CONFIG_DIRS:=/etc/xdg} ; export XDG_CONFIG_DIRS
: ${XDG_DATA_DIRS:='/usr/local/share/:/usr/share/'} ; export XDG_DATA_DIRS
mkdir -p ${XDG_DESKTOP_DIR:=/Desktop}; export XDG_DESKTOP_DIR
mkdir -p ${XDG_DOCUMENTS_DIR:=/Documents}; export XDG_DOCUMENTS_DIR
mkdir -p ${XDG_DOWNLOAD_DIR:=/Downloads}; export XDG_DOWNLOAD_DIR
mkdir -p ${XDG_MUSIC_DIR:=/Music}; export XDG_MUSIC_DIR
mkdir -p ${XDG_PICTURES_DIR:=/Pictures}; export XDG_PICTURES_DIR
mkdir -p ${XDG_PUBLICSHARE_DIR:=/Public}; export XDG_PUBLICSHARE_DIR
mkdir -p -m 0700 ${XDG_RUNTIME_DIR:=/tmp}; export XDG_RUNTIME_DIR
mkdir -p ${XDG_TEMPLATES_DIR:=/insert}; export XDG_TEMPLATES_DIR
mkdir -p ${XDG_VIDEOS_DIR:=/Movies}; export XDG_VIDEOS_DIR

basic w32 fixups〉=
(when (eq system-type 'windows-nt)
  (setenv "XDG_CONFIG_HOME"
          (format "C:\Users\%s\AppData\Roaming\" user-login-name))
  ;; Fix the appearance of Emacs' window
  (setq tess-screen-height-to-type-size-ratio 70
        tess-emacs-top 10
        tess-emacs-left 10)
  ;; Fix assumptions about where things are
  (setenv "HOME" (getenv "USERPROFILE"))
  (cd "~/"))

define data-vol and shared-home for emacs〉=
(defconst tess-mac-data-volume
  "/Volumes/data/")

(defconst tess-mac-shared-home (let ((dir (expand-file-name (format "Users/%s" user-login-name) tess-mac-data-volume))) (if (file-directory-p dir) dir "~/shared")))

Local config overrides

For my shell, I have a local config file that gets loaded at the end of .zshrc.

Load post.zsh〉=
if [[ -r $XDG_CONFIG_HOME/zsh/post.zsh ]]; then
    . $XDG_CONFIG_HOME/zsh/post.zsh
fi

For Emacs and Gnus, it's simpler. Each only has one local file, which run after .emacs and .gnus, respectively.

Custom hooks〉=
(defvar tess-before-local-init-hook nil
  "Hook run before my local init file gets loaded.")
(defvar tess-after-local-init-hook nil
  "Hook run after my local init file gets loaded.")

Host-specific customizations〉=
(run-hooks 'tess-before-local-init-hook)
(require 'local nil t)
(run-hooks 'tess-after-local-init-hook)

Local Gnus configuration〉=
(require 'local-gnus nil t)

Shells and terminals

Intricate Brocade〉=
I don’t want to lose a single thread
from the intricate brocade of this
  happiness.
I want to remember everything.
Which is why I’m lying awake, sleepy
but not sleepy enough to give it up.
Just now, a moment from years ago:
the early morning light, the deft, sweet
gesture of your hand
  reaching for me.
        — Mary Oliver
zsh template〉=
(let ((zsh-template "template.zsh"))
  (when (file-exists-p (expand-file-name zsh-template
                                         auto-insert-directory))
    (add-to-list 'auto-insert-alist
                 `(("\\.zsh\\'" . "Z-Shell") . ,zsh-template))))
insert/.fs-literal〉=
insert/template.zsh〉=
#!/usr/bin/env zsh

emulate -LR zsh

Features common to all shells

Cursors

There is nothing worse than blinking cursors.

Disable blinking cursors〉=
(when (fboundp 'blink-cursor-mode)
  (blink-cursor-mode -1))
(setq visible-cursor nil) ; Emacs 22

And here's how to disable a blinking cursor in vi.

.exrc〉=
set flash

cdpath

cdpath〉=
cdpath=(. ~/code ~/specs ~/specs/*)

setq cd-path〉=
(setq cd-path '("./" "/" "/code" "~/specs"))
(setenv "CDPATH" (mapconcat 'identity cd-path path-separator))

ls

Set my preferred colors for ls to use. Directories should be yellow!

How to set your ls colors on Linux systems:

LSC1〉=
no=00:fi=00:di=00;33:ln=00;36:pi=00;34:so=01;32:bd=00;34;46:cd=00;34;43:
LSC2〉=
or=00;36:mi=00;36:ex=00;32:*.tar.=00;31:*.tgz=00;31:*.arj=00;31:
LSC3〉=
*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:
LSC4〉=
*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:
ls in linux〉=
export LS_COLORS='〈LSC1〉〈LSC2〉〈LSC3〉〈LSC4〉'
export LC_COLLATE='C'
alias ls='ls -FN --color'
LC COLLATE (Emacs)〉=
;; Fix sort order in dired, ls, etc.
(setenv "LC_COLLATE" "C")

(when (eq system-type 'darwin) (setq dired-use-ls-dired nil))

How to set your ls colors on FreeBSD and macOS:

FreeBSD ls colors〉=
dxgxCxexcxegedabagDeBe
ls in freebsd〉=
export LSCOLORS='〈FreeBSD ls colors〉'
alias ls='ls -FG'
And in newer PowerShells, there's experimental support for colors in `Get-ChildItem`, its `ls` equivalent.
PowerShell dir colors〉=
if ($PSVersionTable.PSVersion.Major -ge 7) {
    if (-not [ExperimentalFeature]::IsEnabled("PSAnsiRenderingFileInfo")) {
        Enable-ExperimentalFeature PSAnsiRenderingFileInfo
    } else {
        $PSStyle.FileInfo.Directory = $PSStyle.Foreground.Yellow
        $PSStyle.FileInfo.SymbolicLink = $PSStyle.Foreground.BrightCyan
        $PSStyle.FileInfo.Executable = $PSStyle.Foreground.BrightGreen

    if ($null -ne $Env:PATHEXT) {
        foreach ($ext in $Env:PATHEXT -split [IO.Path]::PathSeparator) {
            $PSStyle.FileInfo.Extension[$ext.ToLower()] = $PSStyle.Foreground.BrightGreen
        }
    }
}

}

ls in PowerShell is very verbose by default. Here's an attempt at making it less so.

ls (PowerShell)〉=
Set-Alias -Name ls -Value Get-ChildItemName -Option AllScope

.local/share/powershell/Modules/Get-ChildItemName/Get-ChildItemName.psm1〉=
if (-not $IsWindows) {
    $lsflags = @('-F')

if ($IsLinux) {
    $Env:LS_COLORS='〈<a href='#lsc1'>LSC1</a>〉〈<a href='#lsc2'>LSC2</a>〉〈<a href='#lsc3'>LSC3</a>〉〈<a href='#lsc4'>LSC4</a>〉'
    $lsflags += '--color'
} else {
    $Env:LSCOLORS='〈<a href='#freebsd-ls-colors'>FreeBSD ls colors</a>〉'
    $lsflags += '-G'
}

function Get-UnixFileListing {
    & (Get-Command ls -Type Application).Source @lsflags @args
    Write-Host
}

}

<# .SYNOPSIS

Get-ChildItemName is a compact form of Get-ChildItem, for people who are used to a more Unix-y 'ls'. #> function Get-ChildItemName { [CmdletBinding()] param( [string]$Path='.', [Alias('a')] [switch] $Force=$false, [Alias('l')] [switch] $Long=$false, [Alias('al','la')] [switch] $ForceAndLong=$false, [Alias('F')] [switch] $UseSigils=$false, [Alias('G')] [switch] $UseColor=$false, [Alias('FG','GF')] [switch] $UseColorAndSigils=$true # My preference )

if ($ForceAndLong) {
    $Force=$true
    $Long=$true
}

if ($UseColorAndSigils) {
    $UseSigils=$true
    $UseColor=$true
}

$gci_args=@{
    Path=$Path
    Force=$Force
    Exclude='NTUSER.*' # Should probably think of a cleaner way to do this
}

# Unless you've passed -a in, we should ignore dotfiles like
# `ls` on Unix does.
if (-not $force) {
    $gci_args['Exclude']='.*'
}

$files = Get-ChildItem @gci_args | Sort-Object -CaseSensitive

if ($files.Count -eq 0) {
    return
} elseif ($Long) {
    $files | Format-Table -AutoSize
    return
}

$max = 0

foreach ($file in $files) {
    if ($file.name.length -gt $max) {
        $max = $file.name.length
    }
}

$max += 1 # room for at least one space after the filename

if ($UseSigils) {
    $max += 1
}

$ncols = [Math]::max(1, [Math]::floor($Host.UI.RawUI.WindowSize.Width / $max))
$nlines = [Math]::ceiling($files.count / $ncols)

[System.IO.FileSystemInfo[][]]$grid=[System.IO.FileSystemInfo[][]]::new($nlines,$ncols)

# Build the grid in column-major order
$fenum = @($files).GetEnumerator()
if ($fenum.MoveNext()) {
    foreach ($col in 0..($ncols-1)) {
        foreach ($row in 0..($nlines-1)) {
            $grid[$row][$col] = $fenum.Current
            if (-not $fenum.MoveNext()) {
                break
            }
        }
    }
}

# Display the grid in row-major order
foreach ($row in 0..($nlines-1)) {
    foreach ($col in 0..($ncols-1)) {
        $file=$grid[$row][$col]

        if (-not $file) {
            break
        }

        $nspaces = $max - $file.Name.Length
        if ($UseSigils) {
            $nspaces -= 1
        }

        $UnixType='-'
        if ($file.UnixMode) {
            $UnixType=$file.UnixMode[0]
        }

        $nameArgs = @{}

        $ansiPre=''
        $ansiPost=''
        if ($UseColor) {
            $UnixRegularFileBits=0b1000000000000000 # S_IFREG
            $UnixExecuteBits=0b1001001

            if ($file.LinkTarget) {
                $nameArgs['Foreground'] = 'Cyan'
            } elseif ($file.PSIsContainer) {
                $nameArgs['Foreground'] = 'DarkYellow'
            } elseif ($file.UnixMode -and ($UnixType -eq 's')) {
                $ansiPre=$PSStyle.Bold
                $ansiPost=$PSStyle.Reset
                $nameArgs['Foreground'] = 'Green'
            } elseif ($file.UnixMode -and ($UnixType -eq 'b')) {
                $nameArgs['Background'] = 'Cyan'
                $nameArgs['Foreground'] = 'DarkBlue'
            } elseif ($file.UnixMode -and ($UnixType -eq 'c')) {
                $nameArgs['Background'] = 'DarkYellow'
                $nameArgs['Foreground'] = 'DarkBlue'
            } elseif ($file.UnixMode -and ($UnixType -eq 'p')) {
                $nameArgs['Foreground'] = 'DarkBlue'
            } elseif ($file.UnixStat -and
                      ($file.UnixStat.Mode -band $UnixRegularFileBits) -and
                      ($file.UnixStat.Mode -band $UnixExecuteBits)) {
                $nameArgs['Foreground'] = 'Green'
            } elseif ($file.Name.EndsWith('~')) {
                $nameArgs['Foreground'] = 'DarkGray'
            } elseif ($file.Extension -and
                      $PSStyle.FileInfo.Extension.ContainsKey($File.Extension.ToLower())) {
                $ansiPre=$PSStyle.FileInfo.Extension[$file.Extension]
                $ansiPost=$PSStyle.Reset
            }
        }
        Write-Host ('{0}{1}{2}' -f $ansiPre,$file.Name,$ansiPost) @nameArgs -NoNewLine

        if ($UseSigils) {
            if ($file.LinkTarget) {
                $sigil = '@'#
            } elseif ($file.PSIsContainer) {
                $sigil = '/'
            } elseif ($file.UnixMode -and ($UnixType -eq 's')) {
                $sigil = '='
            } elseif ($file.UnixMode -and ($UnixType -eq 'p')) {
                $sigil = '|'
            } elseif ($file.UnixStat -and
                      ($file.UnixStat.Mode -band $UnixRegularFileBits) -and
                      ($file.UnixStat.Mode -band $UnixExecuteBits)) {
                $sigil = '*'
            } elseif ($file.Extension -and
                      $file.Extension.ToUpper() -in
                      ($Env:PATHEXT -split [IO.Path]::PathSeparator)) {
                $sigil = '*'
            } else {
                $sigil = ' '
            }
            Write-Host $sigil -NoNewLine
        }

        Write-Host (' '*$nspaces) -NoNewLine
    }
    Write-Host
}

}

if ($IsWindows) { Export-ModuleMember -Function Get-ChildItemName } else { Export-ModuleMember -Function Get-ChildItemName,Get-UnixFileListing }

Path

Set exec-path from path_helper on macOS〉=
(when (file-executable-p "/usr/libexec/path_helper")
  (setq exec-path
        (split-string
         (substring (tess-run-executable "/usr/libexec/path_helper" "-c")
                    13 -2)
         path-separator)))

When I have a separate data partition on Mac, make sure I set up my path appropriately.

Setting PATH in Zsh〉=
add-to-path /Volumes/data/Users/`id -un`/bin || add-to-path ~/shared/bin

Config data-vol and shared-home (Emacs)〉=
(let ((shared-bin
       (expand-file-name "bin" tess-mac-shared-home)))
  (when (file-directory-p shared-bin)
    (add-to-list 'exec-path shared-bin)))

Fix exec-path under Emacs〉=
(defun tess-score-path (path)
  "Score PATH for sorting `exec-path' entries."
  (+ (if (string-match (regexp-quote (expand-file-name "~")) path) 100 0)
     (length path)))

(defun tess-cmp-path (p1 p2) "Non-nil iff P1 should appear before P2 in `exec-path'." (> (tess-score-path p1) (tess-score-path p2)))

(defun tess-path-fixup () "Update `exec-path' with my preferred ordering." (setq exec-path (sort (seq-uniq (mapcar (lambda (p) (file-name-as-directory (expand-file-name p))) exec-path) 'string-equal) 'tess-cmp-path)) (setenv "PATH" (mapconcat 'identity exec-path path-separator)))

(add-hook 'tess-after-local-init-hook 'tess-path-fixup)

Fix exec-path under Windows〉=
(defun tess-fix-w32-pathname (dir)
  "Munge DIR to be a real dir name."
  (setq dir (or dir ""))
  ;; FIXME: an example of why I do this would be nice.
  (if (string-match "^["]\(.*\)["]/\'" dir)
      (file-name-as-directory (match-string 1 dir))
    dir))

(let ((path (parse-colon-path (getenv "PATH")))) (setenv "PATH" (mapconcat 'tess-fix-w32-pathname path path-separator)))

Prompts

Ensure precmd_functions is declared〉=
typeset -aU precmd_functions

Here's how I include the current git branch and revision in my prompt if the current directory is in a git repo.

Setting my prompt〉=
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' get-revision true
zstyle ':vcs_info:git*' formats '%F{8}[%f%b%F{8}@%f%7.7i%F{8}]%f%m'
precmd_functions+=(vcs_info)

RPROMPT=''

update-prompt() { emulate -L zsh

local usercolor=206 # very pink
if (( `id -u` == 0 )); then
    usercolor=9 # very red
fi

PROMPT=$'\n''%m%F{8}:%F{3}%~'$'\n'"%(?.%F{10}✓%f.%F{9}×%f) ${vcs_info_msg_0_:-%F{$usercolor\}%n}%F{8}%(!.#.:)%f "

}

precmd_functions+=(update-prompt)

Setting my prompt in bash〉=
PS1="\n\h:\w\n\u$ "

Setting my prompt (PowerShell)〉=
# PROMPT

$X11RGB=@{ DeepPink=0xff1493 Khaki=0xf0e68c MediumOrchid=0xba55d3 RebeccaPurple=0x663399 }

function Prompt { $LastCommandSucceeded=$?

if ($IsWindows) {
    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = [Security.Principal.WindowsPrincipal] $identity
    $adminRole = [Security.Principal.WIndowsBuiltInRole]::Administrator
    $isRoot = $principal.IsInRole($adminRole)
    $promptchar = '>'
} else {
    $isRoot = ($(id -u) -eq 0)
    $promptchar = ':'
}

$human = [Environment]::UserName.ToLower()
$compy = [Environment]::MachineName.ToLower()

$here = Get-Location
$here = $here.Path -replace ('^'+[Regex]::escape($here.Provider.Home)),'~'

$hostColor=$PSStyle.Foreground.BrightWhite
$delimColor=$PSStyle.Foreground.BrightBlack
$dirColor=$PSStyle.Foreground.Yellow

if ($LastCommandSucceeded) {
    $checkColor=$PSStyle.Foreground.Green
    $check='✓'
} else {
    $checkColor=$PSStyle.Foreground.Red
    $check='×'
}

Write-Host ("`n{0}{1}{2}:{3}{4}" -f $hostColor,$compy,$delimColor,$dirColor,$here)

if ($isRoot) {
    $userColor=$PSStyle.Foreground.Red
    $delimColor=$PSStyle.Foreground.Red
} else {
    $userColor=$PSStyle.Foreground.BrightMagenta
}

Write-Host ('{0}{1} {2}{3}{4}{5}{6}{7}' -f $checkColor,$check,$userColor,$human,$PSStyle.Reset,$delimColor,$promptchar,$PSStyle.Reset) -NoNewLine

return ' '

}

Eshell prompt〉=
(defconst tess-eshell-prompt-format-string
  (let ((user (or (getenv "USER") (user-login-name) "tess"))
        (host (car (split-string
                    (or (getenv "HOST") (system-name) "unknown")
                    "\.")))
        (char (if (= (user-uid) 0) ?# ?:)))
    (format "\n%s@%s\n%s%c " user host "%c %s" char)))

Eshell prompt〉=
(defun tess-eshell-prompt ()
  (format tess-eshell-prompt-format-string
          (if (= eshell-last-command-status 0) ?✓ ?×)
          (abbreviate-file-name default-directory)))

Eshell prompt〉=
(setq eshell-prompt-function 'tess-eshell-prompt)
(setq eshell-prompt-regexp "^[^#:\n]*[#:] ")

Setting my prompt in sh〉=
PS1="${USER}@$(hostname -s): "

Shell aliases and functions

cd
cdlnk (PowerShell)〉=
function Set-LocationFromLink {
    param(
        [Parameter(Position=0)]
        [ArgumentCompleter({
            param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
            $components = $wordToComplete -split [IO.Path]::DirectorySeparatorChar
            $components[$components.count - 1] = $components[$components.count - 1] + '*.lnk'
            (Join-Paths @components | Get-ChildItem).Name
        })]
        [string]$Link
    )

if ($Link.EndsWith('.lnk')) {
    $Link = (Resolve-Path $Link).Path
    $WScriptShell = New-Object -com wscript.shell
    Set-Location $WScriptShell.CreateShortcut($Link).TargetPath
} else {
    Set-Location $Link
}

}

Set-Alias -Name cdlnk -Value Set-LocationFromLink

top
top (PowerShell)〉=
if (Get-Command taskmgr 2> $null) {
    Set-Alias -Name amon -Value taskmgr
    Set-Alias -Name top -Value taskmgr
} elseif (Get-Command oa 2> $null) {
    function Start-ActivityMonitor {
        oa 'Activity Monitor'
    }
    Set-Alias -Name amon -Value Start-ActivityMonitor
}

touch

Powershell doesn't have touch.

touch (PowerShell)〉=
if (-not (Get-Command touch 2> $null)) {
    <#
    .SYNOPSIS

Set-LastWriteTime will update the LastWriteTime of the given files. If
they don't exist, it'll create them, like the Unix 'touch' command.
#>
function Set-LastWriteTime {
    param(
        [Parameter(ValueFromRemainingArguments)]
        [string[]]$files
    )
    foreach ($f in $files) {
        if (Test-Path $f) {
            (Get-ChildItem $f).LastWriteTime = Get-Date
        } else {
            New-Item $f | Out-Null
        }
    }
}
Set-Alias -Name touch -Value Set-LastWriteTime

}

less

PowerShell doesn't have less, but Git for Windows comes with it.

less (PowerShell)〉=
if ($Env:ProgramFiles) {
    $GitLess = Join-Paths ${Env:ProgramFiles} 'Git' 'usr' 'bin' 'less.exe'
    if (Test-Path $GitLess -PathType Leaf) {
        Set-Alias -Name less -Value $GitLess
    } else {
        Set-Alias -Name less -Value more
    }
} elseif (-not (Get-Command less 2> $null)) {
    Set-Alias -Name less -Value more
}

which
which (PowerShell)〉=
<#
.SYNOPSIS

Get-CommandSource locates commands and tells you where they are.

.DESCRIPTION

Get-CommandSource locates the alias, application, cmdlet, function, or script, much like 'which' or 'whence' in Unix shells.

.PARAMETER Command

Specifies the command to look up.

.INPUTS

None. You cannot pipe commands to Get-CommandSource.

.EXAMPLE

PS> Get-CommandSource cmd

CommandType Source


Application C:\WINDOWS\system32\cmd.exe

#> function Get-CommandSource { param( [Parameter(Mandatory=$true)] [string]$Command )

$info = Get-Command $Command
switch ($info.CommandType) {
    'Alias' {
        $info | Select CommandType,Name,Definition
    }
    'Cmdlet' {
        $info | Select CommandType,Name
    }
    'Function' {
        $info | Select CommandType,Name
    }
    Default { # 'ExternalScript','Application'
        $info | Select CommandType,Source
    }
}

}

Set-Alias -Name whence -Value Get-CommandSource Set-Alias -Name which -Value Get-CommandSource

rmb — remove Emacs backup files

I've made this a function in zsh because I don't want it to complain about no matches. There's probably a more elegant way to do this.

Remove Emacs backup files in Zsh〉=
rmb() {
    emulate -L zsh
    set -o null_glob
    local -a files=(*~ .*~)
    if (( $#files > 0 )); then
        rm $files
        print removed $files
    fi
}

Remove Emacs backup files in PowerShell〉=
<#
.SYNOPSIS

Remove-EmacsBackupFiles removes all the Emacs backup files in the current directory.

.DESCRIPTION

Emacs has an auto-save feature which makes backups of files you're editing. These backup files have the same name as the original file, with a U+007E TILDE (~) tacked onto the end. I've long had an 'rmb' shell alias on Unix machines that removes these things. Remove-EmacsBackupFiles is my PowerShell equivalent.

.INPUTS

None. You cannot pipe commands to Remove-EmacsBackupFiles.

#> function Remove-EmacsBackupFiles { $backup_files = Get-ChildItem -Path *~ -Force if ($backup_files.count -gt 0) { Write-Host ('removed {0}' -f ($backup_files.Name -join ' ')) } $backup_files | Remove-Item -Force } Set-Alias -Name rmb -Value Remove-EmacsBackupFiles

On macOS, I use oa to figure out additional aliases to set.

Define MAC_APPS〉=
typeset -A MAC_APPS
MAC_APPS[amon]='Activity Monitor'
MAC_APPS[brave]='Brave Browser'
MAC_APPS[chrome]='Google Chrome'
MAC_APPS[dutil]='Disk Utility'
MAC_APPS[edge]='Microsoft Edge'
MAC_APPS[element]='Element'
MAC_APPS[excel]='Microsoft Excel'
MAC_APPS[eyedropper]='Digital Color Meter'
MAC_APPS[ff]='Firefox'
MAC_APPS[ft]='FaceTime'
MAC_APPS[jabber]='Cisco Jabber'
MAC_APPS[kca]='Keychain Access'
MAC_APPS[marked]='Marked 2'
MAC_APPS[otp]='OTP Auth'
MAC_APPS[prefs]='System Preferences'
MAC_APPS[settings]='System Preferences'
MAC_APPS[slack]='Slack'
MAC_APPS[store]='App Store'
MAC_APPS[stp]='Safari Technology Preview'
MAC_APPS[teams]='Microsoft Teams'
MAC_APPS[webex]='Cisco Webex Meetings'
MAC_APPS[zoom]='zoom.us'

Use a mac-app-launcher placeholder function for all MAC_APPS〉=
mac-app-launcher() {
    if [[ $0 = 'mac-app-launcher' ]]; then
        print "$0: do not call me directly!" >& 2
        return 1
    fi

local shortcut=$0
local app=$MAC_APPS[$shortcut]

unfunction $shortcut

if oa -dq $app; then
    alias $shortcut="oa '$app'"
    rehash
    oa $app
else
    local retval=$?
    print "$app not found!" >& 2
    return $retval
fi

} for shortcut in ${(k)MAC_APPS}; do functions -c mac-app-launcher $shortcut done

Setting PATH in Zsh〉=
if command-recognized osascript; then
    add-to-path ~/code/osa-toys/Scripts
fi
macOS shell aliases〉=
if command-recognized mDNSResponder; then
    alias flush-dns-cache='sudo killall -HUP mDNSResponder'
fi

edge in PowerShell〉=
function edge {
    if ($args.count -gt 0) {
        Start-Process -FilePath msedge -ArgumentList @args
    } else {
        Start-Process -FilePath msedge
    }
}

Emacs & VS Code on macOS〉=
emacs_app=oa -d Emacs 2> /dev/null
if (( $? == 0 )); then
    alias emacs="$emacs_app/Contents/MacOS/Emacs -nw"
    add-to-path $emacs_app/Contents/MacOS/bin
fi
unset emacs_app

Emacs & VS Code on macOS〉=
vscode_app=oa -d 'Visual Studio Code' 2> /dev/null
if (( $? == 0 )); then
    add-to-path "${vscode_app}/Contents/Resources/app/bin"
fi
unset vscode_app
hostname aliases〉=
ssh_hosts=("${(@f)$(grep '^Host[ ][^*]' ~/.ssh/config | cut -c 6-)}")

for host in $ssh_hosts; do if [[ $host == hostname -s ]]; then continue fi alias $host="ssh -t $host screen -DR" alias x$host="ssh -t $host screen -x" done

Configure completion for recvcfg in Zsh

get and put functions〉=
get() {
    emulate -L zsh
    if (( $# != 1 )); then
        print 'USAGE: get host:file' >& 2
        return 1
    fi
    rsync -LPv $1 ${${(s<:>)1}[2]:t}
}

put() { emulate -L zsh if (( $# != 2 )); then print 'USAGE: put file host' >& 2 return 1 fi rsync -LPv $1 ${2}:$1 }

_put() { emulate -L zsh _arguments ':file:_files' ":host:($ssh_hosts[*])" } compdef _put put

Configure completion for recvcfg in Zsh〉=
_recvcfg() {
    emulate -L zsh
    _arguments ":host:($ssh_hosts[*])"
}
compdef _recvcfg recvcfg
mallow (PowerShell)〉=
<#
.SYNOPSIS

Connect-RemoteHost SSHes to a remote host and runs a command on it. #> function Connect-RemoteHost { [CmdletBinding(PositionalBinding=$false)] param( [string]$RemoteHost='mallow.cfhp.org', [string]$RemoteUser='tess', [Parameter(ValueFromRemainingArguments)] [string[]]$RemoteCommand=@('screen','-DR') ) ssh -t $RemoteUser@$RemoteHost @RemoteCommand if (-not $?) { Write-Error "Unable to ${RemoteCommand} on ${RemoteHost} as ${RemoteUser}!" return } } Set-Alias -Name mallow -Value Connect-RemoteHost

Shell completion

Turn on file completion.

git completion〉=
if [[ ! -f $XDG_CONFIG_HOME/zsh/git-completion.zsh ]]; then
    GIT_CONTRIB=~/code/git/contrib
    if [[ -d $GIT_CONTRIB/completion ]]; then
        cp $GIT_CONTRIB/completion/git-completion.{bash,zsh} \
           $XDG_CONFIG_HOME/zsh
    fi
    unset GIT_CONTRIB
fi

if [[ -f $XDG_CONFIG_HOME/zsh/git-completion.zsh ]]; then . $XDG_CONFIG_HOME/zsh/git-completion.zsh 2>& /dev/null fi

if command-recognized gh; then if [[ ! -f $XDG_DATA_HOME/zsh/functions/_gh ]]; then gh completion -s zsh > $XDG_DATA_HOME/zsh/functions/_gh fi compdef _gh gh fi

Use case-insensitive completion in zsh〉=
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'

setq completion-ignore-case〉=
(setq completion-ignore-case t)
case-insensitive filename completion〉=
(setq read-file-name-completion-ignore-case t)

Disable SPC minibuffer completion〉=
(define-key minibuffer-local-completion-map (kbd "SPC") nil)

pcomplete〉=
(setq pcomplete-cycle-completions nil)
Custom completion〉=
autoload -Uz compinit
for dump in ~/.zcompdump(N.m1); do
    compinit
done
compinit -C

Use case-insensitive completion in zsh〉 〈git completion

Some Unix systems have a group per user, and some don't. Try to configure my umask to do the right thing on either kind of Unix.

Set my umask〉=
if [[ `id -un` = `id -gn` ]]; then
    umask 002
else
    umask 022
fi

Use Emacs key bindings for command line editing in zsh.

Use Emacs key bindings for line editing in zsh〉=
bindkey -e

Use Emacs key bindings for line editing (PowerShell)〉=
# Use Emacs keybindings in the line editor
Set-PSReadLineOption -EditMode Emacs

zsh

I relatively recently switched my default shell to zsh.

Don't complain about patterns with no match unless none of them match. FIXME: explain why I changed this from csh_null_glob due to cdpath.

Interactive shell options〉=
set -o null_glob

Display possible completions on second TAB

Interactive shell options〉=
set -o bash_auto_list

Prevent default.profraw files from being created〉=
export LLVM_PROFILE_FILE=/dev/null

Zsh config files

What Zsh config files get loaded, and in which order:

. .zshenv
` -o login ` && . .zprofile
` -o interactive ` && . .zshrc
` -o login ` && . .zlogin
.zshenv
.zshenv〉=
Configure SYSNAME in Zsh〉
〈Disable Apple Terminal shell sessions〉
〈Nethack settings〉
〈Set ORGANIZATION〉
〈Prevent default.profraw files from being created〉
〈Ensure NODE_PATH is set up properly〉
〈configure rust environment〉
〈Use less as my pager〉
〈Configure XDG_CONFIG_HOME and XDG_DATA_HOME
##### `.zprofile`
.zprofile〉=
Configure XDG
##### `.zshrc`
.zshrc〉=
Set my umask〉
〈Don't add duplicate entries to path or fpath〉
〈Tell Zsh where to look for function definitions〉
〈Wrappers around whence to make my zsh config more readable〉
〈Setting PATH in Zsh〉
〈Add ~/SYSNAME/bin to PATH〉
〈Interactive shell options〉
〈cdpath〉
〈Use Emacs key bindings for line editing in zsh〉
〈Configure ls colors〉
〈OS-specific tweaks〉
〈FreeBSD keymap〉
if command-recognized oa; then
    〈Define MAC_APPS〉
    〈Emacs & VS Code on macOS〉
fi

tnc() { ping -c 4 8.8.8.8 } 〈WSL: Ensure runemacs.exe is in PATH〉 〈Choose which editor to use〉 〈Custom completion〉 〈ip in Zsh〉 〈dr in Zsh〉 〈ssid in Zsh〉 〈Remove Emacs backup files in Zsh〉 〈byte-compile command〉 〈hostname aliases〉 〈get and put functions〉 〈Use keychain when available〉 〈Reconnect to SSH agent within screen〉 unset ssh_hosts

Ensure precmd_functions is declared〉 〈Setting my prompt〉 〈Load post.zsh

This has to happen after post.zsh is loaded, so my local config can

add other values to $MAC_APPS.

if command-recognized oa; then 〈Use a mac-app-launcher placeholder function for all MAC_APPS〉 fi

.zlogin
.zlogin〉=
CAT=cat

if command-recognized lolcat; then CAT=lolcat fi

Run fortune at login〉 unset CAT

bash

Sometimes I find myself in bash.

.bashrc〉=
# .bashrc

Configure ls colors

Setting my prompt in bash

PowerShell

On Windows I use PowerShell.

Configure powershell-mode in Emacs〉=
(add-hook 'powershell-mode-hook 'subword-mode)

Get-BatteryStatus〉=
function Get-BatteryStatus {
    $BatteryInfo = Get-WmiObject Win32_Battery
    $BatteryName = $BatteryInfo.caption
    $ChargePercentage = $BatteryInfo.EstimatedChargeRemaining

$ert = $BatteryInfo.EstimatedRunTime
$ert_hours = [Math]::Floor($ert / 60)
$ert_minutes = ($ert - ($ert_hours * 60))

$ttfc = $BatteryInfo.TimeToFullCharge
$ttfc_hours = [Math]::Floor($ttfc / 60)
$ttfc_minutes = ($ttfc - ($ttfc_hours * 60))

$discharging = '{0}: {1}% ({2}:{3:00} remaining)' -f $BatteryName,$ChargePercentage,$ert_hours,$ert_minutes

switch ($BatteryInfo.BatteryStatus) {
    1  { Write-Host $discharging    ; Break } # Fully charged
    2  { Write-Host 'On AC power'   ; Break } # On AC power; battery is not necessarily charging
    3  { Write-Host $discharging    ; Break } # Fully charged
    4  { Write-Warning $discharging ; Break } # Low battery
    5  { Write-Error $discharging   ; Break } # Critical
    10 { Write-Host $discharging    ; Break } # Fully charged
    11 { Write-Host $discharging    ; Break } # Fully charged
    default { # All other states are charging
        '{0}: charging, currently at {1}% ({2}:{3:00} to full charge)' -f $BatteryName,$ChargePercentage,$ttfc_hours,$ttfc_minutes | Write-Host
        Break
    }
}

}

Is PowerShell interactive or a login shell?〉=
# Figure out if this instance of PowerShell is interactive or a login

shell. It's too bad I have to do this logic myself.

See also https://github.com/PowerShell/PowerShell/issues/16689

$InteractiveFlags=@('-Interactive','-i') $NonInteractiveFlags=@('-NonInteractive','-noni') $LoginFlags=@('-Login','-l')

$IsInteractive=$true $IsLoginShell=$false

$narg = 0 foreach ($arg in [Environment]::GetCommandLineArgs()) { if ($arg -in $InteractiveFlags) { $IsInteractive=$true } elseif ($arg -in $NonInteractiveFlags) { $IsInteractive=$false } elseif ($arg -in $LoginFlags -and $narg -eq 1) { $IsLoginShell=$true } $narg += 1 }

.config/powershell/profile.ps1〉=
# Tess' PowerShell config file -- powershell --

Is PowerShell interactive or a login shell?〉 〈Configure SYSNAME in PowerShell

Setting PATH in PowerShell

if ($IsInteractive) { 〈Setting my prompt (PowerShell)〉 # Key bindings

〈<a href='#use-emacs-key-bindings-for-line-editing-powershell'>Use Emacs key bindings for line editing (PowerShell)</a>〉

# Make C-d exit the shell
Set-PSReadlineKeyHandler -Key ctrl+d -Function DeleteCharOrExit

if (Get-Command Get-WmiObject 2> $null) {
    〈<a href='#getbatterystatus'>Get-BatteryStatus</a>〉
    〈<a href='#cdlnk-powershell'>cdlnk (PowerShell)</a>〉
}
if (Get-Command Get-NetRoute 2> $null) {
    〈<a href='#dr-in-powershell'>dr in PowerShell</a>〉
}
〈<a href='#edge-in-powershell'>edge in PowerShell</a>〉
〈<a href='#emacs-powershell'>Emacs (PowerShell)</a>〉
〈<a href='#fortune-powershell'>fortune (PowerShell)</a>〉
if (Get-Command Get-NetIPAddress 2> $null) {
    〈<a href='#ip-in-powershell'>ip in PowerShell</a>〉
}
〈<a href='#less-powershell'>less (PowerShell)</a>〉
〈<a href='#ls-powershell'>ls (PowerShell)</a>〉
〈<a href='#powershell-dir-colors'>PowerShell dir colors</a>〉
〈<a href='#mallow-powershell'>mallow (PowerShell)</a>〉
if (Get-Command nmake 2> $null) {
    Set-Alias -Name make -Value nmake
}
〈<a href='#recvcfg-alias-powershell'>recvcfg alias (PowerShell)</a>〉
〈<a href='#remove-emacs-backup-files-in-powershell'>Remove Emacs backup files in PowerShell</a>〉
if (Get-Command Get-NetConnectionProfile 2> $null) {
    〈<a href='#ssid-in-powershell'>ssid in PowerShell</a>〉
}
〈<a href='#top-powershell'>top (PowerShell)</a>〉
〈<a href='#touch-powershell'>touch (PowerShell)</a>〉
if (-not (Get-Command unzip 2> $null)) {
    Set-Alias -Name unzip -Value Expand-Archive
}
〈<a href='#which-powershell'>which (PowerShell)</a>〉
if (-not (Get-Command zip 2> $null)) {
    Set-Alias -Name zip -Value Compress-Archive
}

if ($Env:ProgramFiles) {
    〈<a href='#game-launchers'>game launchers</a>〉
}

〈<a href='#add-visual-studio-tools-to-path'>Add Visual Studio tools to PATH</a>〉

}

Run fortune at login (PowerShell)

Clean up PowerShell's PATH

When SSHed into a machine from Windows, C-SPC doesn't get correctly sent to the other side by Windows. Here's an alternate keybinding for set-mark-command I can use in such cases.

alternate set-mark-command keybinding〉=
(global-set-key (kbd "C-c m") 'set-mark-command)

Eshell

Make C-a in Eshell jump to the end of the prompt〉=
(add-hook 'eshell-mode-hook
          (lambda ()
            (local-set-key (kbd "C-a") 'eshell-bol)))
eshell faces〉=
'(eshell-prompt-face ((t (〈prompt face〉))))
'(eshell-prompt ((t (〈prompt face〉))))

The Emacs Shell〉=
(when (not (fboundp 'eshell))
  (autoload 'eshell "eshell" nil t))

Make C-a in Eshell jump to the end of the prompt

The Emacs Shell〉=
(setq eshell-cd-on-directory nil)

The Emacs Shell〉=
(setq eshell-save-history-on-exit t
      eshell-hist-ignoredups      nil)

The Emacs Shell〉=
(setq eshell-default-target-is-dot t
      eshell-pushd-tohome          t)

The Emacs Shell〉=
(setq eshell-cmpl-cycle-completions nil)

The Emacs Shell〉=
(if (memq system-type '(berkeley-unix darwin))
    (defun tess-eshell-C-t ()
      "Request status of the running Eshell command.
Only works on BSD."
      (interactive)
      ;; An anamorphic `when' would be nice here.
      (let ((proc (eshell-interactive-process)))
        (if proc
            (process-send-string proc (string 20))
          (call-interactively 'transpose-chars))))
  (defun tess-eshell-C-t ()
    (interactive)
    (ding)))
(add-hook 'eshell-mode-hook
          (lambda ()
            (local-set-key (kbd "C-t") 'tess-eshell-C-t)))
Use ANSI escape sequences in Eshell〉=
(autoload 'ansi-color-filter-apply "ansi-color")
(add-hook 'eshell-preoutput-filter-functions 'ansi-color-filter-apply)

fix s-p in eshell〉=
(add-hook 'eshell-mode-hook
          (lambda ()
            (local-set-key (kbd "s-p")
                           'eshell-previous-matching-input-from-input)))

Use less as my pager〉=
export PAGER='less'

Various custom Eshell commands〉=
(defun eshell/less (file)
  "Pager view of FILE."
  (view-file file)
  0)
(defalias 'eshell/more 'eshell/less)

Various custom Eshell commands〉=
(defun eshell/rmb ()
  "Remove Emacs backup files in this directory."
  (mapconcat (lambda (filename)
               (delete-file filename)
               filename)
             (directory-files default-directory nil "~\'" t)
             ", "))
Various custom Eshell commands〉=
(setq eshell-scroll-show-maximum-output nil)
(defalias 'eshell/clear 'tess-clear)

Various custom Eshell commands〉=
(defun eshell/info (subject)
  "Read the Info manual on SUBJECT."
  (let ((buf (current-buffer)))
    (Info-directory)
    (let ((node-exists (ignore-errors (Info-menu subject))))
      (if node-exists
          0
        (switch-to-buffer buf)
        (eshell-print (format "There is no Info manual on %s.\n"
                              subject))
        1))))

Various custom Eshell commands〉=
(defun eshell/emacs (&rest args)
  "Open a file in Emacs. Some habits die hard."
  (if (null args)
      (bury-buffer)
    (mapc 'find-file (mapcar 'expand-file-name
                             (eshell-flatten-list args))))
  0)
  (defalias 'eshell/emacsclient 'eshell/emacs)

Various custom Eshell commands〉=
(defun eshell/vi (file)
  "Open a file with Viper."
  (with-current-buffer (find-file file)
    (setq viper-mode t)
    (viper-mode))
  0)

Various custom Eshell commands〉=
(defalias 'eshell/concat 'eshell/cat)

Augment eshell's ls to allow middle-clicking on files〉=
(defvar tess-eshell-ls-keymap
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "RET")      'tess-eshell-ls-find-file-at-point)
    (define-key map (kbd "") 'tess-eshell-ls-find-file-at-point)
    (define-key map (kbd "")
      'pat-eshell-ls-find-file-at-mouse-click)
    map))

(defadvice eshell-ls-decorated-name (after tess-electrify-ls activate) "Eshell's `ls' now lets you click or RET on file names to open them." (add-text-properties 0 (length ad-return-value) (list 'help-echo "RET, middle-click: visit this file" 'mouse-face 'highlight 'keymap tess-eshell-ls-keymap) ad-return-value) ad-return-value)

Augment eshell's ls to allow middle-clicking on files〉=
(defun tess-eshell-ls-find-file-at-point (point)
  "RET on Eshell's `ls' output to open files."
  (interactive "d")
  (find-file (buffer-substring-no-properties
              (previous-single-property-change point 'help-echo)
              (next-single-property-change point 'help-echo))))

Augment eshell's ls to allow middle-clicking on files〉=
;; Not defined in Emacs.
(unless (fboundp 'event-point)
  (defun event-point (event)
    "Return the character position of mouse EVENT."
    (posn-point (event-end event))))

(defun pat-eshell-ls-find-file-at-mouse-click (event) "Middle click on Eshell's ls' output to open files. From Patrick Anderson via the EmacsWiki." (interactive "e") (tess-eshell-ls-find-file-at-point (event-point event))) </code></pre></figure><figure id='eshell-faces-206'><figcaption>〈<a href='#eshell-faces-206'>eshell faces</a>〉=</figcaption><pre><code>'(eshell-ls-archive-face ((t (:foreground "〈<a href='#medium-red'>medium red</a>〉")))) '(eshell-ls-archive ((t (:foreground "〈<a href='#medium-red'>medium red</a>〉")))) '(eshell-ls-backup-face ((t (:foreground "〈<a href='#medium-blue'>medium blue</a>〉")))) '(eshell-ls-backup ((t (:foreground "〈<a href='#medium-blue'>medium blue</a>〉")))) '(eshell-ls-clutter-face ((t (〈<a href='#warning-face'>warning face</a>〉)))) '(eshell-ls-clutter ((t (〈<a href='#warning-face'>warning face</a>〉)))) '(eshell-ls-directory-face ((t (〈<a href='#directory-face'>directory face</a>〉)))) '(eshell-ls-directory ((t (〈<a href='#directory-face'>directory face</a>〉)))) '(eshell-ls-executable-face ((t (〈<a href='#executable-face'>executable face</a>〉)))) '(eshell-ls-executable ((t (〈<a href='#executable-face'>executable face</a>〉)))) '(eshell-ls-missing-face ((t (〈<a href='#error-face'>error face</a>〉)))) '(eshell-ls-missing ((t (〈<a href='#error-face'>error face</a>〉)))) (eshell-ls-product-face ((t 〈dim this face when appropriate〉))) (eshell-ls-product ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) (eshell-ls-readonly-face ((t 〈dim this face when appropriate〉))) `(eshell-ls-readonly ((t 〈dim this face when appropriate〉))) '(eshell-ls-special-face ((t (:foreground "〈light magenta〉")))) '(eshell-ls-special ((t (:foreground "〈light magenta〉")))) '(eshell-ls-symlink-face ((t (〈symlink face〉)))) '(eshell-ls-symlink ((t (〈symlink face〉)))) '(eshell-ls-unreadable-face ((t (〈error face〉)))) '(eshell-ls-unreadable ((t (〈error face〉))))

xterm, comint, gnu screen

Set LANG (Emacs)〉=
(setenv "LANG" "en_US.UTF-8")
TTY terminal-coding-system〉=
(when (fboundp 'set-terminal-coding-system)
  (set-terminal-coding-system 'utf-8))

256 colors in screen〉=
term screen-256color

256 colors (Emacs)〉=
(autoload 'xterm-register-default-colors "term/xterm")
(when (and (not window-system)
           (string-match "256color" (or (getenv "TERMCAP") "")))
  (xterm-register-default-colors xterm-standard-colors))

Arrow keys in local screen instances〉=
(when (and (not (display-graphic-p))
           (string-match "screen-256color" (or (getenv "TERMCAP") "")))
  (global-set-key (kbd "M-[ A") (kbd ""))
  (global-set-key (kbd "M-[ B") (kbd ""))
  (global-set-key (kbd "M-[ C") (kbd ""))
  (global-set-key (kbd "M-[ D") (kbd "")))
Use C-z for screen cmd char〉=
escape ^Zz
.screenrc〉=
256 colors in screen〉
autodetach on
〈enable screen's nethack mode〉
deflogin on
startup_message off
defscrollback 2048
chdir
shell "-/bin/zsh"
〈Use C-z for screen cmd char〉
encoding UTF-8 UTF-8
hardstatus lastline "%H | %-w%{+b r}%n %t%{-}%+w"
.screenrc〉=
markkeys "h=^B:l=^F:$=^E"
.screenrc〉=
screen -t Emacs 0 emacs -nw
Use keychain when available〉=
if command-recognized keychain; then
    if [[ -o login && -f ${HOME}/.ssh/id_rsa ]]; then
        . ${HOME}/.keychain/${HOST}-sh
    fi
fi
Reconnect to SSH agent within screen〉=
# http://www.tolaris.com/2011/07/12/

reconnecting-your-ssh-agent-to-a-detached-gnu-screen-session/

if [[ $TERM =~ 'screen*' && -v SSH_CONNECTION ]]; then alias get_ssh_auth_sock="find /tmp/ssh-* -user $USERNAME -name agent* | tail -n 1" export SSH_AUTH_SOCK=get_ssh_auth_sock print "Fixing SSH_AUTH_SOCK [basename $SSH_AUTH_SOCK]." fi

xterm colors〉=
xtermVT100background: 〈darkest black〉
xtermVT100foreground: 〈medium white〉
xtermcolor7:           〈medium white〉
xtermcolor15:          〈light white〉
xtermcolor0:           〈darkest black〉
xtermcolor8:           〈medium black〉
xtermcolor1:           〈medium red〉
xtermcolor9:           〈light red〉
xtermcolor2:           〈dark green〉
xtermcolor10:          DarkSeaGreen2
xtermcolor3:           〈medium yellow〉
xtermcolor11:          〈light yellow〉
xtermcolor4:           〈medium blue〉
xtermcolor12:          〈light blue〉
xtermcolor5:           〈medium magenta〉
xtermcolor13:          〈light magenta〉
xtermcolor6:           〈dark cyan〉
xtermcolor14:          〈medium cyan

comint faces〉=
'(comint-highlight-input ((t (:bold t))))
'(comint-highlight-prompt ((t (〈prompt face〉))))

term faces〉=
(setq ansi-term-color-vector
  [unspecified "〈darkest black〉" "〈dark red〉"
   "〈dark green〉" "〈dark yellow〉" "〈dark blue〉"
   "〈light magenta〉" "〈medium cyan〉" "〈dark white〉"])

xterm-frobs.el fetch rule〉=
xterm-frobs.el:
        curl -O ftp://ftp.splode.com/pub/users/friedman/emacs-lisp/xterm-frobs.el
defun tess-frob-xterm〉=
(defun tess-frob-xterm (frame)
  (when (and (tess-xterm-p) (require 'xterm-frobs nil t))
    (mapc
     (lambda (pair)
       (let ((key (car pair))
             (value (cdr pair)))
         (cond
          ((eq key 'foreground-color) (xterm-set-background-color value))
          ((eq key 'background-color) (xterm-set-foreground-color value))
          ((eq key 'mouse-color) (xterm-set-mouse-foreground-color value))
          ((eq key 'cursor-color) (xterm-set-cursor-color value)))))
     default-frame-alist)))

(add-hook 'after-make-frame-functions 'tess-frob-xterm)

ANSI colors

ANSI color sequences〉=
(autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
### don't echo passwords in comint
Don't echo passwords in comint mode〉=
(add-hook 'comint-output-filter-functions
          'comint-watch-for-password-prompt)

Apple Terminal

Disable Apple Terminal shell sessions〉=
if [[ $TERM_PROGRAM = 'Apple_Terminal' ]]; then
    export SHELL_SESSIONS_DISABLE=1
fi

Emacs

Soft Animal〉=
Let the soft animal of your body love what it loves.
        — Mary Oliver

I've been a heavy Emacs user for over twenty years; my .emacs file has been continuously evolving that whole time.

Emacs UI elements

The Echo Area and *Messages*

Increase logging amount〉=
(setq message-log-max most-positive-fixnum)

Configure Emacs logging levels〉=
(setq display-warning-minimum-level 'error)

The Minibuffer

Minibuffer Electric Default Mode〉=
(when (fboundp 'minibuffer-electric-default-mode)
  (minibuffer-electric-default-mode 1))

Fix size of temporary buffer windows〉=
(when (fboundp 'temp-buffer-resize-mode)
  (temp-buffer-resize-mode 1))

Enable minibuffer resizing〉=
(cond ((not (tess-variable-obsolete-p 'resize-minibuffer-window-exactly))
       (setq resize-minibuffer-window-exactly t)
       (when (fboundp 'resize-minibuffer-mode)
         (resize-minibuffer-mode 1)))
      (t
       (setq max-mini-window-height 0.30)
       (setq resize-mini-window t)))

The mode line

mode-line common〉=
:inverse-video nil :box (:line-width 2 :style released-button)
mode-line bg〉=
:background "〈dark blue (alt)〉"
mode-line fg〉=
default fg
Standard mode-line face〉=
mode-line fg〉 〈mode-line bg〉 〈mode-line common
mode-line faces〉=
'(mode-line ((t (〈Standard mode-line face〉))))
'(modeline ((t (〈Standard mode-line face〉))))
mode-line faces〉=
'(mode-line-inactive ((t (〈mode-line fg〉 :background "〈medium black〉"
                         〈mode-line common〉))))
mode-line faces〉=
'(mode-line-highlight ((t (:foreground "black" :background "light sky blue"
                          〈mode-line common〉))))

Disable Emacs menubar〉=
Emacs*menuBar:             false

disbale menu bar in elisp〉=
(when (fboundp 'menu-bar-mode)
  (menu-bar-mode (tess-menu-bar-lines)))

Scroll bars and scrolling

Fix scrolling〉=
(setq-default scroll-step              1
              scroll-conservatively    most-positive-fixnum
              scroll-up-aggressively   0.0
              scroll-down-aggressively 0.0)

.exrc〉=
set scroll=1

scroll bar〉=
(setq frame-title-format
      (concat (if (string-equal (user-login-name) "root")
                  "SU: "
                "")
              "%b (Emacs on "
              (or (getenv "HOST") (system-name) "unknown")
              ")"))

scroll bar〉=
(when (fboundp 'scroll-bar-mode)
  (scroll-bar-mode -1))

scroll bar〉=
(add-hook 'after-make-frame-functions
          (lambda (frame)
            (when (eq (window-system frame) 'w32)
              (scroll-bar-mode -1))))

Tool bars

Disable Emacs toolbar〉=
Emacs*toolBar:             false
Emacs*verticalScrollBars:  false

tool bar〉=
(when (fboundp 'tool-bar-mode)
  (tool-bar-mode -1)
  (add-to-list 'default-frame-alist '(tool-bar-lines . 0)))

Gutters

gutter〉=
(when (boundp 'default-gutter-visible-p)
  (set-specifier default-gutter-visible-p nil))

gutter〉=
(setq progress-feedback-use-echo-area t)

Tooltips

tooltips〉=
(when (featurep 'tooltip)
  (setq tooltip-gud-tips-p t))
tooltip face〉=
'(tooltip ((t (:background "〈light yellow〉" :foreground "〈dark black〉"
               :box (:line-width 4 :color "〈light yellow〉")
               :inherit variable-pitch :height 120))))

Speedbar

speedbar faces〉=
'(speedbar-button-face ((t (:foreground "〈medium green〉"))))
'(speedbar-directory-face ((t (〈directory face〉))))
'(speedbar-file-face ((t (〈filename face〉))))
'(speedbar-highlight-face ((t (〈highlight face〉))))
'(speedbar-selected-face ((t (〈marked face〉))))
'(speedbar-tag-face ((t (:foreground "〈medium yellow〉"))))

Frames

Disable one-buffer-one-frame-mode〉=
(setq ns-pop-up-frames nil) ; NSEmacs (Emacs.app, aqua, from NeXT Emacs)
(when (fboundp 'one-buffer-one-frame-mode)
  (setq one-buffer-one-frame nil) ; Aquamacs is dumb.
  (one-buffer-one-frame-mode 0))

Disable CUA-mode〉=
(cua-mode 0)
Disable smart-frame-positioning-mode〉=
(when (fboundp 'smart-frame-positioning-mode)
  (smart-frame-positioning-mode 0))

Buffers

Buffer switching: ido, icomplete, iswitchb

Better buffer switching〉=
(cond ((require 'ido nil t)
       (ido-mode 1)
       (setq ido-show-dot-for-dired t)
       (setcar (cddr ido-decorations) ",")
       (setcar (cddr (cdr ido-decorations)) ",…"))
      ((and (fboundp 'icomplete-mode)
            (require 'icomplete nil t)
            ;; Only sufficiently recent versions of icomplete-mode allow
            ;; me to tweak its key bindings to my liking, so we should
            ;; only enable it when that's the case
            (boundp 'icomplete-minibuffer-map))
       (icomplete-mode 1))
      ((fboundp 'iswitchb-mode)
       (iswitchb-mode 1))
      ((fboundp 'iswitchb-default-keybindings)
       (iswitchb-default-keybindings)))
(global-set-key (kbd "C-x C-b") (global-key-binding (kbd "C-x b")))

Better buffer switching〉=
(setq icomplete-show-matches-on-no-input t
      icomplete-separator ","
      read-buffer-completion-ignore-case t)

(eval-after-load "icomplete" '(when (boundp 'icomplete-minibuffer-map) (let ((map icomplete-minibuffer-map)) (define-key map (kbd "C-s") 'icomplete-forward-completions) (define-key map (kbd "C-r") 'icomplete-backward-completions) (define-key map (kbd "RET") 'minibuffer-force-complete-and-exit))))

Better buffer switching〉=
(add-hook 'iswitchb-define-mode-map-hook
          (lambda ()
            (mapc (lambda (key)
                    (define-key iswitchb-mode-map key nil))
                  (list (kbd "C-n") (kbd "C-k")))))

Better buffer switching〉=
(eval-after-load "iswitchb"
  '(add-to-list 'iswitchb-buffer-ignore "[]Completions[]"))

iswitchb faces〉=
'(iswitchb-current-match ((t (:foreground "〈medium cyan〉"))))
'(iswitchb-single-match ((t (:foreground "〈medium green〉"))))
'(iswitchb-invalid-regexp ((t (〈error face〉))))
'(iswitchb-virtual-matches ((t (:foreground "〈dark yellow〉"))))

icomplete faces〉=
'(icomplete-first-match ((t (:foreground "〈medium cyan〉"))))

ido faces〉=
'(ido-first-match ((t (:foreground "〈medium cyan〉"))))
'(ido-indicator ((t ())))
'(ido-only-match ((t (:foreground "〈medium green〉"))))
'(ido-subdir ((t ())))
'(ido-virtual ((t (:foreground "〈dark yellow〉"))))

ibuffer face variables〉=
'(ibuffer-deletion-face 'font-lock-warning-face)
;; '(ibuffer-filter-group-name-face 'bold)
'(ibuffer-marked-face 'font-lock-comment-face)
;; '(ibuffer-title-face 'dired-header)

ibuffer-fontification-alist〉=
(setq
 ibuffer-fontification-alist
 '(;; read-only buffers
   (10 buffer-read-only eshell-ls-readonly-face)
   ;; emacs' "special" buffers
   (15 (string-match "^*" (buffer-name)) eshell-ls-special-face)
   ;; hidden buffers
   (20 (and (string-match "^ " (buffer-name)) (null buffer-file-name))
       eshell-ls-symlink-face)
   ;; help buffers
   (25 (memq major-mode ibuffer-help-buffer-modes)
       eshell-ls-archive-face)
   ;; IRC buffers
   (30 (eq major-mode 'erc-mode) erc-notice-face)
   ;; dired buffers
   (35 (eq major-mode 'dired-mode) eshell-ls-directory-face)))

Key bindings

I have been typing M-o M-s to center the current line since time immemorial. Apparently some recent Emacsen have removed this keybinding. Here's how I restore it.

Restore center-line keybinding〉=
(unless (lookup-key (current-global-map) (kbd "M-o"))
  (let ((parent-map ;; (if (require 'facemenu nil t)
                    ;;   facemenu-keymap
         (make-sparse-keymap)))
    (define-key (current-global-map) (kbd "M-o") parent-map)
    (unless (lookup-key parent-map (kbd "M-s"))
      (define-key parent-map (kbd "M-s") 'center-line))))

Windows modifier key bindings〉=
(setq w32-pass-lwindow-to-system nil
      w32-pass-rwindow-to-system nil
      w32-pass-alt-to-system     nil
      w32-alt-is-meta            t
      w32-pass-apps-to-system    nil
      w32-lwindow-modifier       'super
      w32-rwindow-modifier       'hyper
      w32-apps-modifier          nil)
(define-key function-key-map (kbd "") (kbd ""))
Mac modifier key bindings〉=
(setq ns-alternate-modifier 'super
      ;; ns-function-modifier  'SOMETHING
      ;; ns-control-modifier   'SOMETHING
      ns-command-modifier   'meta)
emacs-app modifiers〉=
AlternateModifier
alt
CommandModifier
meta
ControlModifier
control
FunctionModifier
none
Sun Type 6 USB keyboard key bindings〉=
(global-set-key [SunPowerSwitch] 'save-buffers-kill-emacs)
(global-set-key [SunCut]         'clipboard-kill-region)
(global-set-key [SunCopy]        'clipboard-kill-ring-save)
(global-set-key [SunPaste]       'clipboard-yank)
(global-set-key [find]           'apropos)
(global-set-key [SunOpen]        'find-file)
(global-set-key [cancel]         'keyboard-quit)
(global-set-key [SunProps]       'list-text-properties-at)

Sun keyboard key bindings that we get for free〉=
(global-set-key [f20] 'clipboard-kill-region)
(global-set-key [f16] 'clipboard-kill-ring-save)
(global-set-key [f18] 'clipboard-yank)

Sun keyboard key bindings〉=
(global-set-key [f14] 'undo)
(global-set-key [f12] 'repeat)
(global-set-key [f19] 'apropos)
(global-set-key [f17] 'find-file)
(global-set-key [f11] 'keyboard-quit)

find-function key bindings〉=
(when (fboundp 'find-function-setup-keys)
  (find-function-setup-keys))

Key binding for list-text-properties-at〉=
(when (fboundp 'list-text-properties-at)
  (global-set-key (kbd "C-c p") 'list-text-properties-at))

Key binding for FFAP〉=
(when (fboundp 'find-file-at-point)
  (global-set-key (kbd "C-c F") 'find-file-at-point))

Fix insertchar key binding〉=
(global-set-key [insertchar] 'overwrite-mode)
Key binding for bury-buffer〉=
(mapc (lambda (key)
        (global-set-key key 'bury-buffer))
      (list (kbd "s-z") (kbd "A-z") (kbd "M-z")))

Bindings for the scroll wheel in the mode line〉=
(global-set-key (kbd " ") 'next-buffer)
(global-set-key (kbd " ") 'previous-buffer)

Duplicate some meta keys on super〉=
(global-set-key (kbd "C-s-x") 'eval-defun)
(global-set-key (kbd "s-%") 'query-replace)
(global-set-key (kbd "s-/") 'dabbrev-expand)
(global-set-key (kbd "s-:") 'eval-expression)
(global-set-key (kbd "s-;") 'comment-dwim)
(global-set-key (kbd "s-<") 'beginning-of-buffer)
(global-set-key (kbd "s-") 'just-one-space)
(global-set-key (kbd "s-") 'backward-kill-word)
(global-set-key (kbd "s->") 'end-of-buffer)
(global-set-key (kbd "s-\") 'delete-horizontal-space)
(global-set-key (kbd "s-b") 'backward-word)
(global-set-key (kbd "s-d") 'kill-word)
(global-set-key (kbd "s-f") 'forward-word)
(global-set-key (kbd "s-l") 'downcase-word)
(global-set-key (kbd "s-p") (kbd "M-p"))
(global-set-key (kbd "s-q") 'fill-paragraph)
(global-set-key (kbd "s-v") 'scroll-down)
(global-set-key (kbd "s-w") 'kill-ring-save)
(global-set-key (kbd "s-x") 'execute-extended-command)
(global-set-key (kbd "s-~") 'not-modified)

Selection

transient mark mode〉=
(setq zmacs-regions t)

(when (fboundp 'transient-mark-mode) (transient-mark-mode 1) (setq highlight-nonselected-windows nil mark-even-if-inactive t))

multi-region.el fetch rule〉=
multi-region.el:
        curl -O http://purl.org/NET/wence/multi-region.el
multi-region〉=
(when (require 'multi-region nil t)
  (global-set-key (kbd "C-c 2") multi-region-map))

multi-region faces〉=
'(multi-region-face ((t (〈region face (alt)〉))))

additional rectangle command bindings〉=
(let ((map (make-sparse-keymap)))
  (define-key map (kbd "t") 'string-insert-rectangle)
  (global-set-key (kbd "C-c r") map))

Abbrevs

Enable abbrevs〉=
(setq-default abbrev-mode t)
(when (file-exists-p abbrev-file-name)
  (quietly-read-abbrev-file))
abbrev-definitions〉=
(define-abbrev-table 'objc-mode-abbrev-table '(
    ("while" "while" c-electric-continued-statement 0)
    ("else" "else" c-electric-continued-statement 0)
    ))

abbrev-definitions〉=
(define-abbrev-table 'java-mode-abbrev-table '(
    ("while" "while" c-electric-continued-statement 0)
    ("finally" "finally" c-electric-continued-statement 0)
    ("else" "else" c-electric-continued-statement 0)
    ("catch" "catch" c-electric-continued-statement 0)
    ))

abbrev-definitions〉=
(define-abbrev-table 'c-mode-abbrev-table '(
    ("while" "while" c-electric-continued-statement 0)
    ("else" "else" c-electric-continued-statement 0)
    ))

abbrev-definitions〉=
(define-abbrev-table 'c++-mode-abbrev-table '(
    ("while" "while" c-electric-continued-statement 0)
    ("else" "else" c-electric-continued-statement 0)
    ("catch" "catch" c-electric-continued-statement 0)
    ))

abbrev-definitions〉=
(define-abbrev-table 'global-abbrev-table '(
    ))

Completion

Line wrapping: auto-fill-mode and visual-line-mode

filladapt face variables〉=
;; '(filladapt-debug-indentation-face-1 'highlight)
'(filladapt-debug-indentation-face-2 'secondary-selection)
;; '(filladapt-debug-paragraph-face 'bold)

fill-column〉=
(setq-default fill-column 72)
(setq emacs-lisp-docstring-fill-column 72)

Basic auto-fill configuration〉=
(setq-default auto-fill-function 'do-auto-fill)

Basic auto-fill configuration〉=
(mapc (lambda (mode-hook)
         (add-hook mode-hook 'turn-off-auto-fill))
      '(emacs-lisp-mode-hook sh-mode-hook comint-mode-hook
        shell-mode-hook lisp-mode-hook erc-mode-hook ruby-mode-hook))

defun turn-off-auto-fill〉=
(defun turn-off-auto-fill ()
  "Unconditionally turn off Auto Fill mode."
  (interactive)
  (auto-fill-mode -1))

longlines〉=
(setq longlines-wrap-follows-window-size t)
alias longlines with visual-line-mode〉=
(defalias 'longlines-mode 'visual-line-mode)

Line numbers

setnu.el fetch rule〉=
setnu.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/setnu.el
linum〉=
;; linum from g.e.s -- much better than setnu
(when (and (locate-library "linum") (facep 'fringe))
  (setq linum-format (propertize "%5d " 'face 'fringe)))

Key binding for goto-line〉=
(global-set-key (kbd "C-c l") 'goto-line)

Line and Column numbering〉=
(line-number-mode 1)
(when (fboundp 'column-number-mode)
  (column-number-mode 1))

Dired

dired faces〉=
'(dired-directory ((t (〈directory face〉))))
'(dired-face-directory ((t (〈directory face〉))))
dired faces〉=
'(dired-face-executable ((t (〈executable face〉))))
dired faces〉=
`(dired-ignored ((t 〈dim this face when appropriate〉)))
`(dired-face-boring ((t 〈dim this face when appropriate〉)))
dired faces〉=
`(dired-face-permissions ((t 〈dim this face when appropriate〉)))
'(dired-face-setuid ((t (:bold t 〈executable face〉))))
`(dired-face-socket ((t 〈dim this face when appropriate〉)))
dired faces〉=
'(dired-symlink ((t (〈symlink face〉))))
'(dired-face-symlink ((t (〈symlink face〉))))

wdired.el fetch rule〉=
wdired.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/wdired.el

Dired, the Directory Editor〉=
(require 'dired-x nil t)

Dired, the Directory Editor〉=
(setq dired-dwim-target t)

Dired, the Directory Editor〉=
(setq dired-recursive-deletes 'top
      dired-recursive-copies  'top)

Dired, the Directory Editor〉=
(when (locate-library "wdired")
  (autoload 'wdired-change-to-wdired-mode "wdired" nil t)
  (add-hook 'dired-load-hook
            (lambda ()
              (define-key dired-mode-map (kbd "r")
                'wdired-change-to-wdired-mode))))

dired faces〉=
'(dired-flagged ((t (〈warning face〉))))
'(dired-face-flagged ((t (〈warning face〉))))
dired header face〉=
:foreground "〈medium green〉"
dired faces〉=
'(dired-header ((t (〈dired header face〉))))
'(dired-face-header ((t (〈dired header face〉))))
dired faces〉=
'(dired-mark ((t (:foreground "〈medium yellow〉"))))
dired faces〉=
'(dired-marked ((t (〈marked face〉))))
'(dired-face-marked ((t (〈marked face〉))))
dired faces〉=
'(dired-warning ((t (〈warning face〉))))

dired face variables〉=
;; '(dired-header-face 'dired-header)
;; '(dired-mark-face 'dired-mark)
;; '(dired-marked-face 'dired-marked)
;; '(dired-flagged-face 'dired-flagged)
;; '(dired-warning-face 'dired-warning)
'(dired-directory-face 'dired-directory)
;; '(dired-symlink-face 'dired-symlink)
;; '(dired-ignored-face 'dired-ignored)

Emoji

Emoji utilities〉=
(defvar tess-expand-emoji-flag t
  "Non-nil iff I should fall back to my emoji expansion code.")

(defun tess-emoji-char-p (char) "Non-nil iff CHAR is in the Unicode emoji range." (and ;; Not in blacklist (not (memq char '())) ;; Ranges (or (and (>= char ?\x1f100) (< char ?\x1f700)) (and (>= char ?\x2600) (< char ?\x2800)))))

(defun tess-expand-emoji () "Replace emoji with [unicode name of emoji]." (while (< (point) (point-max)) (let ((char (char-after (point)))) (cond ;; Strip out variation selectors ((and (>= char ?\xfe00) (< char ?\xfe10)) (delete-char 1)) ;; Apple logo ((= char ?\xf8ff) (insert "[Apple Inc.]") (delete-char 1)) ;; Expand emoji ((tess-emoji-char-p char) (insert (format "[%s]" (get-char-code-property (char-after (point)) 'name))) (delete-char 1)) ;; Skip other charaters (t (goto-char (1+ (point))))))))

(defun tess-fixup-emoji-on-mac () "Make Emacs display emoji correctly on Mac." (set-fontset-font t 'unicode "Apple Color Emoji" nil 'prepend) ;; Disable my fallback emoji expansion hack. (setq tess-expand-emoji-flag nil))

Emoji in Gnus〉=
(defun tess-gnus-article-treat-emoji ()
  "Expand emoji to [unicode name of emoji] in this article."
  (interactive)
  (when tess-expand-emoji-flag
    (with-current-buffer gnus-article-buffer
      (save-excursion
        (let ((inhibit-read-only t))
          (save-restriction
            (article-goto-body)
            (let (buffer-read-only)
              (tess-expand-emoji)))))
    (gnus-article-fill-long-lines t))))

(eval-after-load "gnus-art" '(add-hook 'gnus-part-display-hook 'tess-gnus-article-treat-emoji))

Emoji in ERC〉=
(defun tess-erc-expand-emoji ()
  "Expand emoji to [unicode name of emoji]."
  (goto-char (point-min))
  (tess-expand-emoji))

(when tess-expand-emoji-flag (add-hook 'erc-insert-modify-hook 'tess-erc-expand-emoji) (add-hook 'erc-send-modify-hook 'tess-erc-expand-emoji))

Emacs theming

color-theme fetch rules〉=
color-theme.el: color-theme.el.gz
        gzip -d -c color-theme.el.gz > color-theme.el
color-theme.el.gz:
        curl -O http://download.gna.org/color-theme/color-theme.el.gz

preferred color themes〉=
color-theme-hober2 color-theme-resolve color-theme-hober
custom-theme〉=
((and (fboundp 'load-theme) (locate-library "hober2-theme"))
 (let ((tess-theme-dir (file-name-directory (locate-library "hober2-theme"))))
   (when (boundp 'custom-theme-load-path)
     (add-to-list 'custom-theme-load-path tess-theme-dir))
   (load "hober2-theme")
   (enable-theme 'hober2)))

color-theme〉=
((require 'color-theme nil t)
  ;; (setq color-theme-is-cumulative nil)
  (require 'color-theme-hober2 nil t)
  (let ((theme (seq-find 'fboundp '(〈preferred color themes〉))))
    (when theme
      (add-hook 'tess-after-local-init-hook theme))))

The hober2 Emacs theme

face-list〉=
(when (locate-library "face-list")
  (autoload 'customize-face-at "face-list" nil t)
  (global-set-key (kbd "C-c f c") 'customize-face-at)

(autoload 'describe-face-at "face-list" nil t) (global-set-key (kbd "C-c f d") 'describe-face-at))

deftheme hober2〉=
(deftheme hober2
  "Color theme by Theresa O'Connor tess@oconnor.cx.

Like my previous theme, I've attempted to make sure things look reasonably similar under console or window system. The colors of hober2-theme' are often washed-out variants of the colors of color-theme-hober'.

Includes antlr, apropos, AUCTeX (font-latex), bbdb, Buffer-menu, calendar, change-log, comint, compilation, cperl, custom, diary, diff, dired, ediff, erc, eshell, filladapt, font-lock, forms, gnus, goto-address, help, highline, hl-line, holiday, html-helper, hyper-apropos, ibuffer, Info, isearch, jde, makefile, Man, message, multi-region, nxml, psvn, sgml, sh, show-paren, show-tabs, slime, sldb, speedbar, tex, view, viper, w3m, widget, woman")

hober2-theme variables〉=
man face variables〉
〈apropos face variables〉
〈cperl face variables〉
〈dired face variables〉
〈erc face variables〉
〈filladapt face variables〉
'(fixed-pitch ((t (:family nil))))
;; '(forms-ro-face 'custom-comment-tag-face)
;; '(forms-rw-face 'custom-comment-face)

goto-address face variables〉 '(help-highlight-face 'font-lock-variable-name-face)

hl-line face variables〉 〈ibuffer face variables〉 ;; '(list-matching-lines-face 'bold) '(list-matching-lines-buffer-name-face 'font-lock-type-face)

;; '(view-highlight-face 'highlight)

viper face variables〉 〈widget face variables

hober2-theme faces〉=
default face〉
〈antlr faces〉
〈bbdb faces〉
〈erc ansi bg faces〉
'(bold ((t (:bold t))))
'(bold-italic ((t (:bold t :slant italic))))

'(border ((t nil)))

'(Buffer-menu-buffer-face ((t (:foreground "〈light yellow〉")))) '(button ((t (〈button face〉))))

'(calendar-today-face ((t (:foreground "〈medium yellow〉"))))

change log faces〉 〈comint faces〉 〈compilation faces〉 〈cperl faces〉 〈css-mode (monnier) faces〉 '(cursor ((t (:background "〈medium yellow〉" 〈dark fg〉))))

Custom faces

hober2-theme faces〉=
'(diary-face ((t (:foreground "〈medium red〉"))))
'(diary-button-face ((t (〈button face〉))))

diff faces〉 〈dired faces〉 〈ediff faces〉 〈erc faces(escape-glyph ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) 〈<a href='#eshell-faces'>eshell faces</a>〉 〈<a href='#erc-ansi-fg-faces'>erc ansi fg faces</a>〉 (file-name-shadow ((t 〈dim this face when appropriate〉))) 〈font latex faces

font lock faces〉 '(fringe ((t (:background "〈dark black (alt)〉" :foreground "〈light white〉"))))

gnus faces〉 '(header-line ((t (:box (:line-width 2 :color "〈dark black (alt)〉" :style nil) :background "〈dark black (alt)〉" :foreground "〈light white〉"))))

help faces〉 〈html helper faces〉 〈hyper apropos faces

hober2-theme faces〉=
'(highlight ((t (〈highlight face〉))))

highline faces〉 '(holiday-face ((t (:foreground "〈light magenta〉"))))

icomplete faces〉 〈ido faces〉 〈info faces〉 〈isearch faces〉 〈iswitchb faces〉 '(italic ((t (:slant italic))))

jde faces〉 〈js2 faces

'(link ((t (:foreground "〈light cyan〉" 〈link face〉))))

'(makefile-shell-face ((t ()))) '(makefile-space-face ((t (〈whitespace face〉)))) '(makefile-targets-face ((t ())))

markdown-mode faces

'(match ((t (:background "〈light blue〉" :foreground "〈medium white〉"))))

'(menu ((t (:background "〈medium white〉" :foreground "〈dark black〉"))))

message faces〉 '(minibuffer-prompt ((t (〈prompt face〉)))) 〈mm faces

mode-line faces〉 '(mouse ((t (:foreground "〈medium yellow〉" 〈default bg〉))))

multi-region faces〉 〈nxml faces〉 〈mic-paren faces〉 〈parenface faces〉 '(primary-selection ((t (〈region face〉)))) 〈psvn faces〉 〈rcirc faces

region bg color〉=
dark blue (alt)
region bg〉=
:background "〈region bg color〉"
region face〉=
:foreground "〈light white〉" 〈region bg
region face (alt)〉=
:background "〈medium blue〉" :foreground "〈light white〉"

hober2-theme faces〉=
'(region ((t (〈region face〉))))

hober2-theme faces〉=
rng faces

'(scroll-bar ((t (:background "〈medium white〉" :foreground "〈dark black〉"))))

hober2-theme faces〉=
'(secondary-selection ((t (〈region face (alt)〉))))

sgml faces〉 `(shadow ((t 〈dim this face when appropriate〉))) 〈shell faces〉 〈show paren faces〉 〈show tabs faces〉 〈slime compliler faces〉 〈slime debugger faces〉 〈slime repl faces〉 〈slime inspector faces〉 〈slime reader faces〉 〈smerge-mode faces〉 〈speedbar faces〉 '(subscript ((t ()))) '(superscript ((t ()))) '(tex-math-face ((t (〈math face〉)))) '(tex-math ((t (〈math face〉)))) '(tex-verbatim-face ((t ()))) '(tex-verbatim ((t ())))

'(tool-bar ((t (〈button face〉)))) 〈tooltip face

'(trailing-whitespace ((t (〈whitespace face〉))))

'(underline ((t (:underline t))))

viper faces〉 〈w3m faces〉 '(whitespace-highlight-face ((t (〈whitespace face〉)))) 〈widget faces〉 〈woman faces〉 '(zmacs-region ((t (〈region face〉))))

widget face variables〉=
;; '(widget-mouse-face 'highlight)
widget faces〉=
'(widget-button-face ((t (〈link face〉))))
'(widget-button-pressed-face ((t (〈link face〉))))
'(widget-documentation-face ((t (:foreground "〈medium green〉"))))
'(widget-field-face ((t (〈default (alt)〉))))
`(widget-inactive-face ((t 〈dim this face when appropriate〉)))
'(widget-single-line-field-face ((t (〈default (alt)〉))))

elisp/hober2-theme.el〉=
;;; hober2-theme.el --- Theresa O'Connor's second theme.

Elisp Copyright Statement

;;; Commentary:

;; This is my second theme. Apologies for the formatting; this ;; file is automatically extracted from a LaTeX master file.

;;; Code:

(require 'dired) ;; FIXME

deftheme hober2

;; Placate the byte compiler and elint (defvar window-system)

defun hober2-use-underline-p

defvar hober2-insignificant-face

(custom-theme-set-variables 'hober2 〈hober2-theme variables〉)

(custom-theme-set-faces 'hober2 〈hober2-theme faces〉)

(provide-theme 'hober2)

;;; hober2-theme.el ends here

Basic faces

darkest black〉=
black
dark black〉=
gray4
dark black (alt)〉=
gray8
medium black〉=
gray30
light black〉=
gray40
dark red〉=
orange red
medium red〉=
indian red
light red〉=
IndianRed1
dark green〉=
DarkGreen
medium green〉=
medium sea green
light green〉=
DarkSeaGreen2
dark yellow〉=
sandy brown
medium yellow〉=
khaki
light yellow〉=
lemon chiffon
dark blue〉=
dark slate blue
dark blue (alt)〉=
#5f5f87
medium blue〉=
LightSteelBlue4
light blue〉=
DodgerBlue3
dark magenta〉=
dark orchid
medium magenta〉=
medium orchid
light magenta〉=
pale violet red
very light magenta〉=
light pink
dark cyan〉=
steel blue
medium cyan〉=
cadet blue
light cyan〉=
light sea green
dark white〉=
gray
medium white〉=
light gray
light white〉=
white
default bg〉=
:background "〈darkest black〉"
default bg (alt)〉=
:background "〈dark black (alt)〉"
default fg〉=
:foreground "〈medium white〉"
default fg (alt)〉=
:foreground "〈dark white〉"
default face〉=
'(default ((t (〈default bg〉 〈default fg〉
               :stipple nil :box nil :strike-through nil :overline nil
               :underline nil :slant normal :weight normal
               :inverse-video nil))))

directory face〉=
:foreground "〈medium yellow〉"
filename face〉=
:foreground "〈medium cyan〉"
executable face〉=
:foreground "〈medium green〉"
cursor color〉=
medium yellow
cursor color (alt)〉=
very light magenta
cursor color (warning)〉=
light magenta
warning face〉=
:background "〈medium red〉" :foreground "〈light white〉"
error face〉=
warning face〉 :bold t
whitespace face〉=
:background "〈light red〉" :foreground "〈medium white〉"
defvar hober2-insignificant-face〉=
(defvar hober2-insignificant-face
  (if window-system
     '(:foreground "〈medium black〉")
   '()))

dim this face when appropriate〉=
,hober2-insignificant-face
cyan bg〉=
:background "〈medium cyan〉"
cyan bg (alt)〉=
:background "〈dark cyan〉"
dark fg〉=
:foreground "〈dark black〉"
dark fg (alt)〉=
:foreground "〈medium black〉"
comment face〉=
:foreground "〈medium magenta〉"
comment delimiter face〉=
comment face (alt)
marked face〉=
cyan bg〉 〈dark fg
comment face (alt)〉=
:foreground "〈dark magenta〉"
prompt face〉=
:foreground "〈light magenta〉"
button face〉=
:foreground "〈dark black〉" :background "〈medium white〉"
:bold t :box (:line-width 1 :style released-button)
pressed button face〉=
:foreground "〈dark black〉" :background "〈medium white〉"
:bold t :box (:line-width 1 :style pressed-button)
default (alt)〉=
:background "〈medium black〉" :foreground "〈light white〉"
highlight face〉=
:background "〈dark green〉" 〈default fg〉 〈link face
compilation faces〉=
'(compilation-warning-face ((t (〈warning face〉))))
'(compilation-warning ((t (〈warning face〉))))
'(compilation-info-face ((t (〈comment face〉))))
'(compilation-info ((t (〈comment face〉))))
'(compilation-error-face ((t (〈comment face〉))))
'(compilation-error ((t (〈comment face〉))))

table-insert

table〉=
(when (locate-library "table")
  (autoload 'table-insert "table" nil t)
  (global-set-key (kbd "C-c t") 'table-insert))

Org mode

ensure org-mode is autoloaded〉=
(when (and (not (fboundp 'org-mode))
           (locate-library "org"))
  (autoload 'org-mode "org" nil t))

org-mode〉=
(add-to-list 'auto-mode-alist '("\.org\'" . org-mode))
(global-set-key (kbd "C-c o l") 'org-store-link)
(global-set-key (kbd "C-c o a") 'org-agenda)

Deft

deft.el fetch rule〉=
deft.el:
        curl -O http://jblevins.org/projects/deft/deft.el

Deft〉=
(setq deft-directory (expand-file-name "~/Notes/")
      deft-text-mode (seq-find 'fboundp '(markdown-mode text-mode)))
(setq deft-extension
      (assoc-default deft-text-mode '((markdown-mode . "md"))
                     'eq "txt"))

;; Completely override Deft's keybindings to be more like Dired and ;; Gnus: (setq deft-mode-map (make-sparse-keymap)) (define-key deft-mode-map (kbd "a") 'deft-new-file-named) (define-key deft-mode-map (kbd "d") 'deft-delete-file) (define-key deft-mode-map (kbd "g") 'deft-refresh) (define-key deft-mode-map (kbd "n") 'next-line) (define-key deft-mode-map (kbd "q") 'quit-window) (define-key deft-mode-map (kbd "p") 'previous-line) (define-key deft-mode-map (kbd "r") 'deft-rename-file) (define-key deft-mode-map (kbd "s") 'deft-filter) (define-key deft-mode-map (kbd "z") 'deft-filter-clear) (define-key deft-mode-map (kbd "") 'deft-complete)

EMMS

EMMS〉=
(when (require 'emms nil t)
  (global-set-key (kbd "s-n") 'emms-next)
  (global-set-key (kbd "s-p") 'emms-previous)
  (global-set-key (kbd "s-s") 'emms-shuffle)
  (global-set-key (kbd "s-") 'emms-play-directory-tree)
  (global-set-key (kbd "s-") 'emms-stop))

tidy.el

tidy.el fetch rule〉=
tidy.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/tidy.el

http-twiddle

http-twiddle.el fetch rule〉=
http-twiddle.el:
        curl -O http://fresh.homeunix.net/~luke/misc/emacs/http-twiddle.el

Mathematics

math face〉=
:foreground "〈dark yellow〉"
Mathematics〉=
(when (locate-library "maxima")
  (autoload 'maxima "maxima" nil t)
  (add-to-list 'auto-mode-alist '("\\.max\\'" . maxima))
  (autoload 'maxima-mode "maxima" nil t))

Mathematics〉=
(when (locate-library "imaxima")
  (autoload 'imaxima "imaxima" nil t)
  (setq imaxima-pt-size 12
        imaxima-fnt-size "Huge"
        imaxima-image-type 'ps
        imaxima-use-maxima-mode-flag (locate-library "maxima")))

DNS

DNS mode〉=
(add-hook 'dns-mode-hook
          (lambda ()
            (add-hook 'before-save-hook
                      'dns-mode-soa-increment-serial
                      nil t)))
### user-mail-address function
defun user-mail-address〉=
(unless (fboundp 'user-mail-address)
  (defun user-mail-address ()
    "Returns the value of the `user-mail-address' variable."
    user-mail-address))

generic x

generic-x〉=
(when (ignore-errors (require 'generic-x))
  (setq default-major-mode 'default-generic-mode))
### Browsers, browser engines, and their bug trackers
TTY web browser default〉=
(setq browse-url-browser-function 'browse-url-lynx-emacs)
Integer thing at point〉=
(defun tess-intatpt-end-op ()
  (while (looking-at "[0-9]")
    (forward-char 1)))
(put 'integer 'end-op 'tess-intatpt-end-op)

(defun tess-intatpt-beginning-op () (unless (looking-at "[0-9]") (backward-char 1)) (while (looking-at "[0-9]") (backward-char 1)) (forward-char 1)) (put 'integer 'beginning-op 'tess-intatpt-beginning-op)

W3M

.w3m/config〉=
# Render frames automatically
frame true

Use ASCII equivalents to display entities

alt_entity true

Display DEL, S and STRIKE element

display_ins_del true

Use URL history

use_history true

Number of remembered URL

history 2048

Save URL history

save_hist true

Confirm when quitting with q

confirm_qq false

Enable Emacs-style line editing

emacs_like_lineedit true

Wrap search

wrap_search true

Search case-insensitively

ignorecase_search true

Enable mouse

use_mouse true

Editor

editor emacsclient

Default value for open-URL command

default_url http://www.google.com/

Enable cookie processing

use_cookie true

Action to be taken on invalid cookie

accept_bad_cookie true

emacs-w3m〉=
(autoload 'w3m "w3m" nil t)
(autoload 'w3m-goto-url "w3m" nil t)
(autoload 'w3m-region "w3m")

emacs-w3m〉=
(setq w3m-home-page
      (if (file-readable-p "/html/home.html")
          (concat "file://" (expand-file-name "/html/home.html"))
        "http://tess.oconnor.cx/home"))

emacs-w3m〉=
(setq w3m-use-toolbar t
      w3m-use-tab     nil
      w3m-key-binding 'info)

emacs-w3m〉=
(setq w3m-search-default-engine "google")

emacs-w3m〉=
(setq w3m-command-arguments       '("-F" "-cookie")
      w3m-mailto-url-function     'compose-mail
      browse-url-browser-function 'w3m
      mm-text-html-renderer       'w3m)

emacs-w3m〉=
(add-hook 'w3m-mode-hook 'tess-hide-trailing-whitespace)

emacs-w3m〉=
(eval-after-load "w3m"
  '(define-key w3m-mode-map (kbd "z") 'bury-buffer))

emacs-w3m〉=
(defalias 'eshell/w3m 'w3m)

disable use of ? as completion help in minibuffer〉=
(define-key minibuffer-local-must-match-map (kbd "?") nil)
(define-key minibuffer-local-completion-map (kbd "?") nil)

emacs-w3m〉=
(setq w3m-use-cookies t)
(setq w3m-cookie-accept-bad-cookies t)

Gnus w3m〉=
(when (fboundp 'w3m)
  (setq mm-inline-text-html-renderer 'w3m))
w3m faces〉=
'(w3m-anchor-face ((t (:foreground "〈light cyan〉" 〈link face〉))))
'(w3m-anchor ((t (:foreground "〈light cyan〉" 〈link face〉))))
'(w3m-arrived-anchor-face ((t (:foreground "〈medium cyan〉" 〈link face〉))))
'(w3m-arrived-anchor ((t (:foreground "〈medium cyan〉" 〈link face〉))))
'(w3m-bitmap-image-face ((t (:foreground "〈dark black〉"
                             :background "〈light white〉"))))
'(w3m-bitmap-image ((t (:foreground "〈dark black〉"
                        :background "〈light white〉"))))
'(w3m-bold-face ((t (:foreground "〈medium green〉"))))
'(w3m-bold ((t (:foreground "〈medium green〉"))))
'(w3m-current-anchor-face ((t (:foreground "〈light cyan〉"
                               :bold t 〈link face〉))))
'(w3m-current-anchor ((t (:foreground "〈light cyan〉"
                          :bold t 〈link face〉))))
'(w3m-form-button-face ((t (〈button face〉))))
'(w3m-form-button ((t (〈button face〉))))
'(w3m-form-button-mouse-face ((t (〈highlight face〉))))
'(w3m-form-button-mouse ((t (〈highlight face〉))))
'(w3m-form-button-pressed-face ((t (〈pressed button face〉))))
'(w3m-form-button-pressed ((t (〈pressed button face〉))))
'(w3m-form-face ((t (〈button face〉))))
'(w3m-form ((t (〈button face〉))))
'(w3m-header-line-location-title-face ((t (:foreground "〈medium cyan〉"))))
'(w3m-header-line-location-title ((t (:foreground "〈medium cyan〉"))))
'(w3m-header-line-location-content-face ((t (:foreground "〈medium yellow〉"))))
'(w3m-header-line-location-content ((t (:foreground "〈medium yellow〉"))))
'(w3m-history-current-url-face ((t (:foreground "〈light yellow〉"))))
'(w3m-history-current-url ((t (:foreground "〈light yellow〉"))))
'(w3m-image-face ((t (:foreground "〈light green〉" :bold t))))
'(w3m-image ((t (:foreground "〈light green〉" :bold t))))
'(w3m-insert-face ((t (:underline t))))
'(w3m-insert ((t (:underline t))))
'(w3m-link-numbering-face ((t (:foreground "〈medium green〉" :bold t))))
'(w3m-link-numbering ((t (:foreground "〈medium green〉" :bold t))))
'(w3m-strike-through-face ((t (:strike-through t :strikethru t))))
'(w3m-strike-through ((t (:strike-through t :strikethru t))))
'(w3m-underline-face ((t (:underline t))))
'(w3m-underline ((t (:underline t))))

defun tess-follow-link-at-point〉=
(defun tess-link-at-point (point)
  "Returns the URL at point, if there is one.
This works for links created by `shr', w3/m, and on URLs embedded in text."
  (interactive "d")
  (let* ((props (text-properties-at point))
         (url (or (plist-get props 'shr-url)
                  (plist-get (plist-get props 'w3-hyperlink-info) :href)
                  (plist-get props 'w3m-href-anchor)
                  (thing-at-point 'url)
                  (error "Couldn't determine link at point."))))
    (when (called-interactively-p 'any)
      (message "%s" url))
    url))

(defun tess-follow-link-at-point (point) "Try to follow an HTML link at point." (interactive "d") (browse-url (tess-link-at-point point)))

(defun tess-display-link-at-point (point) "Display the HTML link at point." (interactive "d") (message "URL at point is %s" (tess-link-at-point point)))

(defun tess-kill-link-at-point (point) "Put the HTML link at point on the kill ring." (interactive "d") (kill-new (tess-link-at-point point)))

(add-hook 'gnus-article-mode-hook (lambda () (local-set-key (kbd "C-c a") 'tess-follow-link-at-point) (local-set-key (kbd "C-c k") 'tess-kill-link-at-point)))

goto-address〉=
(when (fboundp 'goto-address)
  (setq goto-address-fontify-maximum-size most-positive-fixnum)
  (add-hook 'find-file-hooks 'goto-address))

goto-address face variables〉=
'(goto-address-url-face 'font-lock-string-face)
;; '(goto-address-url-mouse-face 'highlight)
'(goto-address-mail-face 'font-lock-string-face)
;; '(goto-address-mail-mouse-face 'highlight)

Choose the right browser〉=
(global-set-key (kbd "C-c a") 'browse-url)
(cond ((eq system-type 'darwin)
       (setq browse-url-browser-function
             'browse-url-default-macosx-browser))
      (t
       (dolist (candidate '("chromium-browser" "google-chrome"))
         (when (executable-find candidate)
           (setq browse-url-browser-function 'browse-url-generic
                 browse-url-generic-program candidate)))))

lj: URLs in emacs-w3m〉=
(add-to-list 'w3m-uri-replace-alist
             '("\`lj:\(.+\)" w3m-pattern-uri-replace
               "http://www.livejournal.com/users/\\1/"))

LiveJournal

ljupdate, an Emacs LiveJournal client〉=
;; When I have a local copy of my website, use the ljupdate there.
(let ((web-lib "~/web/html/ljupdate/"))
  (when (file-directory-p web-lib)
    (add-to-list 'load-path web-lib)))

(when (require 'ljupdate nil t) (setq lj-cache-login-information t lj-default-username "hober" lj-fill-function 'ignore) (global-set-key (kbd "C-c j c") 'lj-compose) (global-set-key (kbd "C-c j l") 'lj-login) ;; handy for developing / testing in ielm (setq lj "www.livejournal.com" dj "www.deadjournal.com"))

Google

Using Google〉=
(setq google-referer "http://tess.oconnor.cx/")

Using Google〉=
(when (ignore-errors (require 'g))
  (setq g-user-email "hober0@gmail.com"))

Emacs Lisp List

ELL〉=
(when (locate-library "ell")
  (setq ell-locate t)
  (setq ell-goto-addr t)
  (autoload 'ell-packages "ell" nil t))

twitter

twit.el fetch rule〉=
twit.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/twit.el

Using Twitter from within Emacs〉=
(cond ((locate-library "twitter")
       (autoload 'twitter "twitter" nil t)
       (global-set-key (kbd "C-c t") 'twitter))
      ((locate-library "twit")
       (autoload 'twit-post "twit" nil t)))

(when (locate-library "twittering-mode") (autoload 'twit "twittering-mode" nil t) ;; Don't forget to set twittering-password' locally. (setq twittering-username "hober") ;; Work-around for a bug in twittering-mode' in some Emacsen. (unless (fboundp 'clear-image-cache) (defun clear-image-cache (&rest ignore))))

backpack

Using Backpack from within Emacs〉=
(when (locate-library "backpack")
  (setq backpack-username "hober")

(defvar tess-backpack-map (make-sparse-keymap)) (global-set-key (kbd "C-c b") tess-backpack-map)

(mapc (lambda (cons) (let ((command (car cons))) (autoload command "backpack" nil t) (define-key tess-backpack-map (cdr cons) command))) '((backpack-remind . "r") (backpack-remind-from-region . "R"))))

applescript-mode.el fetch rule〉=
applescript-mode.el:
        curl -O http://jaist.dl.sourceforge.jp/macemacsjp/9401/applescript-mode.el

Ensure after-make-frame-functions get run for first frame〉=
(defun tess-run-after-make-frame-functions (&optional frame)
  (run-hook-with-args 'after-make-frame-functions
                      (or frame (selected-frame))))
(add-hook 'tess-after-local-init-hook 'tess-run-after-make-frame-functions)

defsubst tess-alist〉=
(defsubst tess-alist (list)
  "Given LIST of the form (A B .. Z), create an alist of the form
((A . A) (B . B) .. (Z . Z)). If LIST is nil, return nil. Useful
for making arguments for `completing-read'."
  (mapcar (lambda (item) (cons item item)) list))

defun tess-add-to-list*〉=
(defun tess-add-to-list* (list-var &rest directories)
  "Add to the value of LIST-VAR each existing directory in DIRECTORIES.
Effectively a multi-argument version of add-to-list', but custom-made for variables like load-path' and `Info-default-directory-list'."
  (mapc (lambda (directory)
          (when (file-directory-p directory)
            (add-to-list list-var (file-name-as-directory directory))))
        directories))
(put 'tess-add-to-list* 'lisp-indent-function 1)

package.el and install.el

Configuring package.el〉=
(when (= emacs-major-version 26)
  ;; Workaround for `package-refresh-contents' failing in Emacs 26.x
  (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))

(package-initialize)

(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/") ("melpa" . "https://melpa.org/packages/")))

defun tess-install-url〉=
(defun tess-install-url (url)
    (interactive "sURL: ")
    (let ((filename (car (last (split-string url "/")))))
      (when (= 0 (shell-command (format "curl -o %s "%s""
                                        filename url)))
        (install-file filename))))

defun tess-install-url-at-point〉=
(defun tess-install-url-at-point ()
    (interactive)
    (tess-install-url (thing-at-point-url-at-point)))
install.el fetch rule〉=
install.el:
        curl -O http://www.iro.umontreal.ca/~monnier/elisp/install.el
autoloads make rule〉=
autoloads: install.el
        $(EMACS) -batch -L . -l install.el 
-eval '(install-update-autoloads "autoloads")'

who knows

Poor-man's diminish.el〉=
(setcar (cdr (assq 'abbrev-mode minor-mode-alist)) " A")
(setcar (cdr (assq 'auto-fill-function minor-mode-alist)) " F")
(let ((el-hook (lambda () (setq mode-name "el"))))
  (add-hook 'emacs-lisp-mode-hook el-hook)
  (add-hook 'lisp-interaction-mode-hook el-hook))
(add-hook 'sh-mode-hook (lambda () (setq mode-name "sh")))

Macro DWIM stuff〉=
(defun tess-macro-dwim (arg)
  "DWIM keyboard macro recording and executing."
  (interactive "P")
  (if defining-kbd-macro
      (if arg
          (end-kbd-macro arg)
        (end-kbd-macro))
    (if last-kbd-macro
        (call-last-kbd-macro arg)
      (start-kbd-macro arg))))

Macro DWIM stuff〉=
(defun tess-macro-clear ()
  "Clear out the last keyboard macro."
  (interactive)
  (setq last-kbd-macro nil)
  (message "Last keyboard macro cleared."))

Macro DWIM stuff〉=
(global-set-key (kbd "") 'tess-macro-dwim)
(global-set-key (kbd "M-") 'tess-macro-clear)
(define-key esc-map (kbd "") 'tess-macro-clear)
multi-tty C-x C-c hack〉=
(when (featurep 'multi-tty)
  (defun tess-delete-frame-or-kill-emacs ()
    (interactive)
    (if (cdr (frame-list)) ; (> (length (frame-list)) 1)
        (delete-frame)
      (save-buffers-kill-emacs)))
  (global-set-key (kbd "C-x C-c") 'tess-delete-frame-or-kill-emacs))

Define display type predicates〉=
(if (fboundp 'console-type)
    (defun tess-tty-p (&rest ignore)
      "Is this a TTY that we're on?"
      (eq (console-type) 'tty))
  (defun tess-tty-p (&optional display)
    "Is this a TTY that we're on?"
    (not (display-graphic-p display))))

(defun tess-xterm-p (&optional display) "Non-nil if DISPLAY is an xterm. If DISPLAY is nil, the current displaly is used." (and (tess-tty-p display) (let ((TERM (getenv "TERM"))) (if TERM (string-match "^xterm.*\'" TERM) nil))))

Define display type predicates〉=
(defun tess-menu-bar-lines (&optional frame)
  "Returns the number of menu bar lines to be used on FRAME."
  (if (eq (window-system frame) 'ns) 1 0))

Configure load-path〉=
(defsubst tess-expand-file-name-in-code-dir (file)
  (expand-file-name file tess-code-dir))

(apply 'tess-add-to-list* 'load-path (mapcar 'tess-expand-file-name-in-code-dir '("bikeshed/emacs" "editorconfig-emacs" "facebook-el" "gitsum" "ljupdate" "markdown-mode" "mediawiki-el" "ninja/misc" "slime")))

Configure load-path〉=
;; Ducking the incompatible byte-code issue.
(apply 'tess-add-to-list* 'load-path
  (mapcar 'tess-expand-file-name-in-code-dir
          '("37emacs" "auctex" "bbdb/lisp" "circe" "emacs-w3m" "erc"
            "g-client" "gnus/lisp" "js2-mode/build" "nxml")))

Configure Info-default-directory-list〉=
(apply 'tess-add-to-list* 'Info-default-directory-list
  (mapcar 'tess-expand-file-name-in-code-dir
          '("auctex/doc""bbdb/texinfo" "emacs-w3m/doc" "gnus/texi")))

defsubst tess-variable-obsolete-p〉=
(defsubst tess-variable-obsolete-p (variable)
  "Non-nil if VARIABLE is marked as obsolete."
  (get variable 'byte-obsolete-variable))
defun propertize〉=
(defun propertize (string &rest props)
  "Propertize STRING with PROPS.
Copied from `erc-propertize'."
  (let ((length (length string)))
    (while props
      (put-text-property 0 length (car props) (cadr props) string)
      (setq props (cddr props))))
  string)

Emacs' Custom mode

Host-specific customizations〉=
(setq custom-unlispify-tag-names       nil
      custom-unlispify-menu-entries    nil
      custom-unlispify-remove-prefixes nil)

Host-specific customizations〉=
(setq custom-file
      (expand-file-name (format "Emacs-%d-custom.el" emacs-major-version)
                        tess-elisp-dir))
(load custom-file t)
Custom faces〉=
'(custom-button ((t (〈button face〉))))
'(custom-button-face ((t (〈button face〉))))
'(custom-button-pressed ((t (〈pressed button face〉))))
'(custom-button-pressed-face ((t (〈pressed button face〉))))
'(custom-face-tag ((t (:bold t))))
'(custom-face-tag-face ((t (:bold t))))
'(custom-variable-tag ((t (:bold t))))
'(custom-variable-tag-face ((t (:bold t))))
'(custom-state ((t (:foreground "〈medium green〉"))))
'(custom-state-face ((t (:foreground "〈medium green〉"))))

Show tabs

show tabs faces〉=
'(show-tabs-space ((t (〈whitespace face〉))))
'(show-tabs-space-face ((t (〈whitespace face〉))))
'(show-tabs-tab ((t (〈whitespace face〉))))
'(show-tabs-tab-face ((t (〈whitespace face〉))))

Trailing whitespace

Highlight Trailing Whitespace〉=
(if (boundp 'show-trailing-whitespace)
    (progn
      〈Enable highlighting trailing whitespace for Emacs 21〉)
  (defalias 'tess-hide-trailing-whitespace 'ignore))

Enable highlighting trailing whitespace for Emacs 21〉=
(setq-default show-trailing-whitespace t)

(defun tess-hide-trailing-whitespace () "Do not highlight trailing whitespace in this buffer." (interactive) (setq show-trailing-whitespace nil))

(defun tess-show-trailing-whitespace () "Highlight trailing whitespace in this buffer." (interactive) (setq show-trailing-whitespace t))

(defun tess-toggle-show-trailing-whitespace () "Highlight trailing whitespace in this buffer." (interactive) (setq show-trailing-whitespace (not show-trailing-whitespace)))

(mapc (lambda (mode-hook) (add-hook mode-hook 'tess-hide-trailing-whitespace)) '(Buffer-menu-mode-hook custom-mode-hook text-mode-hook term-mode-hook Info-mode-hook comint-mode-hook buffer-menu-mode-hook apropos-mode-hook tooltip-show-hook gnus-article-mode-hook mail-mode-hook gnus-summary-mode-hook message-mode-hook gnus-group-mode-hook eshell-mode-hook w3-mode-hook initial-calendar-window-hook))

(mapc (lambda (mode-hook) (add-hook mode-hook 'tess-show-trailing-whitespace)) '(latex-mode-hook LaTeX-mode-hook html-mode-hook))

Emacs in various window systems

Windowing〉=
Configuring the frame alists〉
〈disbale menu bar in elisp〉
(when (display-graphic-p)
  〈scroll bar〉
  〈tool bar〉
  〈tooltips〉)

(when (display-graphic-p) 〈Mouse focus〉 〈Fix pasting in X11〉 (cond ((fboundp 'mouse-wheel-mode) 〈mouse-wheel-mode〉) ((locate-library "mwheel") 〈mwheel〉)))

emacs-app default-frame-alist〉=
Left
0
Top
22
InternalBorderWidth
2
Menus
YES
VerticalScrollBars
NO

Fonts

Monospaced 12〉=
-*-bitstream vera sans mono-medium-r-*-*-12-*-*-*-*-*-*-*
Monospaced 12 Bold〉=
-*-bitstream vera sans mono-bold-r-*-*-12-*-*-*-*-*-*-*
Monospaced 14〉=
-*-bitstream vera sans mono-medium-r-*-*-14-*-*-*-*-*-*-*
Monospaced 14 Bold〉=
-*-bitstream vera sans mono-bold-r-*-*-14-*-*-*-*-*-*-*
lucidatypewriter 17〉=
-*-lucidatypewriter-medium-r-*-*-17-*-*-*-*-*-*-*
Monospaced 17〉=
-*-bitstream vera sans mono-medium-r-*-*-17-*-*-*-*-*-*-*
Monospaced 18〉=
-*-bitstream vera sans mono-medium-r-*-*-18-*-*-*-*-*-*-*
Monospaced 18 Bold〉=
-*-bitstream vera sans mono-bold-r-*-*-18-*-*-*-*-*-*-*
lucidatypewriter 20〉=
-*-lucidatypewriter-medium-r-*-*-20-*-*-*-*-*-*-*
Monospaced 24〉=
-*-bitstream vera sans mono-medium-r-*-*-24-*-*-*-*-*-*-*
Monospaced 24 Bold〉=
-*-bitstream vera sans mono-bold-r-*-*-24-*-*-*-*-*-*-*

Font configuration〉=
(setq ns-antialias-text t)

Font configuration〉=
(defvar tess-fonts
  '(;; My default
    "Menlo"
    ;; Very nice console fonts from Microsoft
    "Cascadia Code" "Consolas"
    ;; Free-as-in-whatever options
    "Inconsolata" "Ubuntu Mono" "Monospace" "DejaVu Sans Mono"
    ;; Decent defaults on the Mac
    "Andale Mono" "Monaco"
    ;; My old X11 standbys
    "Screen" "Lucida Console"
    ;; A fallback that's on every system ever.
    "Courier")
  "Fonts I like, in decreasing order of preference.")

(defvar tess-typographic-scale '(6 7 8 9 10 11 12 14 16 18 21 24) "The typographic scale used for selecting a font size.")

(defvar tess-screen-height-to-type-size-ratio 56.0 "Ratio of screen height (in pixels) to my preferred type size.")

(defun tess-closest-traditional-type-size (size) "Return the entry in `tess-typographic-scale' closest to SIZE." (caar (sort (mapcar (lambda (candidate) (cons candidate (abs (- size candidate)))) tess-typographic-scale) (lambda (a b) (< (cdr a) (cdr b))))))

(defun tess-guess-font-size () "Guess an appropriate font size for this display." (tess-closest-traditional-type-size (/ (display-pixel-height) tess-screen-height-to-type-size-ratio)))

(defvar tess-font-size (if window-system (tess-guess-font-size) nil) "My preferred font size. Can be overridden in local.el.")

(defun tess-font-spec (font size) (format "%s-%d" font size))

(defun tess-find-font () "Return the first available font listed in `tess-fonts'." (let ((family-list (font-family-list))) (seq-find (lambda (font) (member font family-list)) tess-fonts)))

(defvar tess-font nil "My preferred font. Can be overridden in local.el.")

(defun tess-font-init () (when window-system (setq tess-font (tess-find-font))))

(add-hook 'tess-after-local-init-hook 'tess-font-init)

(defun tess-set-font (&optional font size) "Figure out and install which font and size I use on this system. If called interactively, prompts the user for the font and size to use." (interactive (list (completing-read (format "Font (default %s): " tess-font) (font-family-list) nil t nil nil tess-font) (read-number "Size: " (tess-guess-font-size)))) (let* ((font (or font (tess-find-font))) (size (or size tess-font-size)) (font-spec (tess-font-spec font size))) (setq tess-font-size size) (add-to-list 'default-frame-alist (cons 'font font-spec)) (set-frame-font font-spec)))

(unless (tess-tty-p) (add-hook 'tess-after-local-init-hook 'tess-set-font) ;; Now that we've picked a font, we can fixup Emacs' fontset to ;; correctly display emoji. (when (and (eq (window-system) 'ns) (version<= emacs-version "25.0.91")) (add-hook 'tess-after-local-init-hook 'tess-fixup-emoji-on-mac)))

(when (fboundp 'text-scale-increase) (global-set-key (kbd "M-=") 'text-scale-increase) (global-set-key (kbd "M--") 'text-scale-decrease))

emacs-app font settings〉=
Font
Inconsolata
FontSize
18
GSFontAntiAlias
YES
NSFontPanelAttributes
1, 0
NSFontPanelPreviewHeight
0.0
NSWindow Frame NSFontPanel
1001 153 445 270 0 0 1680 1028 
UseQuickdrawSmoothing
NO

Emacs geometry at startup

Configuring the frame alists〉=
(setq default-frame-alist '())

defun tess-frob-xterm〉 〈Font configuration

(add-to-list 'default-frame-alist '(wait-for-wm . nil)) (add-to-list 'default-frame-alist (cons 'menu-bar-lines (tess-menu-bar-lines)))

(defvar tess-emacs-width nil "Iff non-null, the initial width that Emacs should use.") (defvar tess-emacs-height nil "Iff non-null, the initial height that Emacs should use.") (defvar tess-emacs-top nil "Iff non-null, the initial top that Emacs should use.") (defvar tess-emacs-left nil "Iff non-null, the initial left that Emacs should use.")

(defun tess-reset-emacs-geometry () (set-frame-parameter nil 'width tess-emacs-width) (set-frame-parameter nil 'height tess-emacs-height) (set-frame-parameter nil 'top 0) (set-frame-parameter nil 'left 0))

(defun tess-respond-to-screen-geometry () (interactive) (tess-set-font nil (tess-guess-font-size)) (setq tess-emacs-width 81) (cond ((= (display-pixel-width) 1280) ;; 12" MacBooks (setq tess-emacs-height 46)) ((and (= (display-pixel-width) 1366) ;; yt (eq system-type 'gnu/linux)) (setq tess-emacs-height 34)) ((and (= (display-pixel-width) 1366) ;; oban (eq system-type 'darwin)) (setq tess-emacs-height 44)) ((= (display-pixel-width) 1512) ;; MacBookPro18,3 (setq tess-emacs-height 43)) ((= (display-pixel-width) 1920) ;; XPS (setq tess-emacs-height 24)) ((= (display-pixel-width) 2240) ;; 21" M1 iMac (setq tess-emacs-height 50)) ((= (display-pixel-width) 2560) ;; LG UltraFine (setq tess-emacs-height 49))) (tess-reset-emacs-geometry))

(defun tess-init-emacs-geometry () (when window-system (when tess-emacs-width (add-to-list 'default-frame-alist (cons 'width tess-emacs-width))) (when tess-emacs-height (add-to-list 'default-frame-alist (cons 'height tess-emacs-height))) (when tess-emacs-left (add-to-list 'default-frame-alist (cons 'left tess-emacs-left))) (when tess-emacs-top (add-to-list 'default-frame-alist (cons 'top tess-emacs-top)))) ;; Finally, ensure both frame alists are the same. (setq initial-frame-alist default-frame-alist))

(add-hook 'tess-before-local-init-hook 'tess-init-emacs-geometry)

(when window-system (add-hook 'tess-after-local-init-hook 'tess-respond-to-screen-geometry))

Emacs stack size

max-lisp-eval-depth〉=
1500
max-specpdl-size〉=
3000
Configure max-lisp-eval-depth and max-specpdl-size〉=
(setq max-lisp-eval-depth 〈max-lisp-eval-depth〉
      max-specpdl-size    〈max-specpdl-size〉)

Garbage collect when tabbing away from Emacs〉=
(add-hook 'focus-out-hook 'garbage-collect)

Mouse wheels

mouse-wheel-mode〉=
(mouse-wheel-mode 1)
mwheel〉=
(unless (fboundp 'mwheel-install)
  (autoload 'mwheel-install "mwheel" nil nil))
(setq mwheel-follow-mouse t)
(setq mwheel-scroll-amount '(4 . 1))
(mwheel-install)
Mouse focus〉=
(setq focus-follows-mouse (eq (window-system) 'x)
      mouse-autoselect-window t)

Indicate emtpy lines

indicate-empty-lines〉=
(setq-default indicate-empty-lines       t
              indicate-buffer-boundaries t)

indicate-empty-lines〉=
(let ((hook (lambda ()
              (setq indicate-empty-lines       nil
                    indicate-buffer-boundaries nil)))
      (mode-hooks '(shell-mode-hook term-mode-hook gnus-article-mode-hook
                    gnus-summary-mode-hook gnus-group-mode-hook
                    eshell-mode-hook)))
  (mapc (lambda (mode-hook)
          (add-hook mode-hook hook))
        mode-hooks))

CSV in Emacs

csv.el fetch rule〉=
csv.el:
        curl -o csv.el http://ulf.epplejasper.de/downloads/csv.el

CSV〉=
(autoload 'csv-parse-buffer "csv")

DOM and HTTP libraries for Emacs

dom.el fetch rule〉=
dom.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/dom.el

http-FOO.el fetch rules〉=
SAVANNAH_VIEWVC=http://cvs.savannah.gnu.org/viewvc/*checkout*
http-cookies.el http-get.el http-post.el:
        curl -o $.el $(SAVANNAH_VIEWVC)/http-emacs/$.el?root=http-emacs

Local variable specs

defun tess-insert-local-variables-spec〉=
(defun tess-insert-local-variables-spec ()
  "Insert a minimal local variables spec for this buffer."
  (interactive)
  (save-excursion
    (save-restriction
      (widen)
      (goto-char (point-min))
      (insert (format "-*- mode: %s; coding: %s -*- "
                      ;; FIXME: only strip when last 5 characters are "-mode"
                      (substring (symbol-name major-mode) 0 -5)
                      ;; FIXME: "-unix" is 5 chars, but what about the others?
                      (substring (symbol-name buffer-file-coding-system) 0 -5)))
      ;; If there's some kind of local comment syntax, ensure the local
      ;; variables spec lives in one.
      (when comment-start
        (comment-region (point-min) (1- (point))))
      (delete-char -1)
      (insert "\n"))))

HTML entities

html4 entity map〉=
(defvar tess-html4-entity-map
  '(;; latin-1
    ("nbsp" . 160) ("iexcl" . 161) ("cent" . 162) ("pound" . 163)
    ("curren" . 164) ("yen" . 165) ("brvbar" . 166) ("sect" . 167)
    ("uml" . 168) ("copy" . 169) ("ordf" . 170) ("laquo" . 171)
    ("not" . 172) ("shy" . 173) ("reg" . 174) ("macr" . 175)
    ("deg" . 176) ("plusmn" . 177) ("sup2" . 178) ("sup3" . 179)
    ("acute" . 180) ("micro" . 181) ("para" . 182) ("middot" . 183)
    ("cedil" . 184) ("sup1 #185") ("ordm" . 186) ("raquo" . 187)
    ("frac14" . 188) ("frac12" . 189) ("frac34" . 190) ("iquest" . 191)
    ("Agrave" . 192) ("Aacute" . 193) ("Acirc" . 194) ("Atilde" . 195)
    ("Auml" . 196) ("Aring" . 197) ("AElig" . 198) ("Ccedil" . 199)
    ("Egrave" . 200) ("Eacute" . 201) ("Ecirc" . 202) ("Euml" . 203)
    ("Igrave" . 204) ("Iacute" . 205) ("Icirc" . 206) ("Iuml" . 207)
    ("ETH" . 208) ("Ntilde" . 209) ("Ograve" . 210) ("Oacute" . 211)
    ("Ocirc" . 212) ("Otilde" . 213) ("Ouml" . 214) ("times" . 215)
    ("Oslash" . 216) ("Ugrave" . 217) ("Uacute" . 218) ("Ucirc" . 219)
    ("Uuml" . 220) ("Yacute" . 221) ("THORN" . 222) ("szlig" . 223)
    ("agrave" . 224) ("aacute" . 225) ("acirc" . 226) ("atilde" . 227)
    ("auml" . 228) ("aring" . 229) ("aelig" . 230) ("ccedil" . 231)
    ("egrave" . 232) ("eacute" . 233) ("ecirc" . 234) ("euml" . 235)
    ("igrave" . 236) ("iacute" . 237) ("icirc" . 238) ("iuml" . 239)
    ("eth" . 240) ("ntilde" . 241) ("ograve" . 242) ("oacute" . 243)
    ("ocirc" . 244) ("otilde" . 245) ("ouml" . 246) ("divide" . 247)
    ("oslash" . 248) ("ugrave" . 249) ("uacute" . 250) ("ucirc" . 251)
    ("uuml" . 252) ("yacute" . 253) ("thorn" . 254) ("yuml" . 255)
    ;; special
    ; ("quot" . 34) ("amp" . 38) ("lt" . 60) ("gt" . 62)
    ("OElig" . 338) ("oelig" . 339) ("Scaron" . 352) ("scaron" . 353)
    ("Yuml" . 376) ("circ" . 710) ("tilde" . 732) ("ensp" . 8194)
    ("emsp" . 8195) ("thinsp" . 8201) ("zwnj" . 8204) ("zwj" . 8205)
    ("lrm" . 8206) ("rlm" . 8207) ("ndash" . 8211) ("mdash" . 8212)
    ("lsquo" . 8216) ("rsquo" . 8217) ("sbquo" . 8218) ("ldquo" . 8220)
    ("rdquo" . 8221) ("bdquo" . 8222) ("dagger" . 8224) ("Dagger" . 8225)
    ("permil" . 8240) ("lsaquo" . 8249) ("rsaquo" . 8250) ("euro" . 8364)
    ;; symbol
    ("fnof" . 402) ("Alpha" . 913) ("Beta" . 914) ("Gamma" . 915)
    ("Delta" . 916) ("Epsilon" . 917) ("Zeta" . 918) ("Eta" . 919)
    ("Theta" . 920) ("Iota" . 921) ("Kappa" . 922) ("Lambda" . 923)
    ("Mu" . 924) ("Nu" . 925) ("Xi" . 926) ("Omicron" . 927)
    ("Pi" . 928) ("Rho" . 929) ("Sigma" . 931) ("Tau" . 932)
    ("Upsilon" . 933) ("Phi" . 934) ("Chi" . 935) ("Psi" . 936)
    ("Omega" . 937) ("alpha" . 945) ("beta" . 946) ("gamma" . 947)
    ("delta" . 948) ("epsilon" . 949) ("zeta" . 950) ("eta" . 951)
    ("theta" . 952) ("iota" . 953) ("kappa" . 954) ("lambda" . 955)
    ("mu" . 956) ("nu" . 957) ("xi" . 958) ("omicron" . 959)
    ("pi" . 960) ("rho" . 961) ("sigmaf" . 962) ("sigma" . 963)
    ("tau" . 964) ("upsilon" . 965) ("phi" . 966) ("chi" . 967)
    ("psi" . 968) ("omega" . 969) ("thetasym" . 977) ("upsih" . 978)
    ("piv" . 982) ("bull" . 8226) ("hellip" . 8230) ("prime" . 8242)
    ("Prime" . 8243) ("oline" . 8254) ("frasl" . 8260) ("weierp" . 8472)
    ("image" . 8465) ("real" . 8476) ("trade" . 8482) ("alefsym" . 8501)
    ("larr" . 8592) ("uarr" . 8593) ("rarr" . 8594) ("darr" . 8595)
    ("harr" . 8596) ("crarr" . 8629) ("lArr" . 8656) ("uArr" . 8657)
    ("rArr" . 8658) ("dArr" . 8659) ("hArr" . 8660) ("forall" . 8704)
    ("part" . 8706) ("exist" . 8707) ("empty" . 8709) ("nabla" . 8711)
    ("isin" . 8712) ("notin" . 8713) ("ni" . 8715) ("prod" . 8719)
    ("sum" . 8721) ("minus" . 8722) ("lowast" . 8727) ("radic" . 8730)
    ("prop" . 8733) ("infin" . 8734) ("ang" . 8736) ("and" . 8743)
    ("or" . 8744) ("cap" . 8745) ("cup" . 8746) ("int" . 8747)
    ("there4" . 8756) ("sim" . 8764) ("cong" . 8773) ("asymp" . 8776)
    ("ne" . 8800) ("equiv" . 8801) ("le" . 8804) ("ge" . 8805)
    ("sub" . 8834) ("sup" . 8835) ("nsub" . 8836) ("sube" . 8838)
    ("supe" . 8839) ("oplus" . 8853) ("otimes" . 8855) ("perp" . 8869)
    ("sdot" . 8901) ("lceil" . 8968) ("rceil" . 8969) ("lfloor" . 8970)
    ("rfloor" . 8971) ("lang" . 9001) ("rang" . 9002) ("loz" . 9674)
    ("spades" . 9824) ("clubs" . 9827) ("hearts" . 9829) ("diams" . 9830))
  "Alist mapping HTML 4.01 named character entity references to their
  numerical counterparts. Taken from the HTML 4.01 specification:
    http://www.w3.org/TR/html401/")
### tess-run-executable
defun tess-run-executable〉=
(defun tess-run-executable (executable &rest args)
  ""
  (with-temp-buffer
    (apply 'call-process executable nil t nil args)
    (buffer-substring (point-min) (1- (point-max)))))

mwe-log-commands

mwe-log-commands.el fetch rule〉=
mwe-log-commands.el:
        curl -O http://www.foldr.org/~michaelw/emacs/mwe-log-commands.el

ucs-insert

bind ucs-insert to C-c u〉=
(global-set-key (kbd "C-c u") 'ucs-insert)

fix emacs pasting in X11

Fix pasting in X11〉=
(setq-default mouse-yank-at-point t)

tess-wash-smart-quotes

defun tess-wash-smart-quotes〉=
(defun tess-wash-smart-quotes ()
  "Replace MS smart quotes with normal quotes in this buffer."
  (interactive)
  (save-excursion
    (let ((fixes '((342396 . "\"") (342392 . "'") (342387 . "--")
                   (342397 . "\"") (342393 . "'"))))
      (goto-char (point-min))
      (while (/= (point) (point-max))
        (let* ((this (char-after (point)))
               (match (assq this fixes)))
          (when match
            (delete-char 1)
            (insert (cdr match))))
        (forward-char 1)))))

disable emacs splash screen

Disable the Emacs splash screen〉=
(setq inhibit-startup-message t
      initial-major-mode      'lisp-interaction-mode)

fix common emacs typos

Fix common Emacs typos〉=
(global-set-key (kbd "C-x C-g") 'keyboard-quit)
(global-set-key (kbd "C-x C-k") 'kill-buffer)
(global-set-key (kbd "C-x f") 'find-file)

visual bell

visual-bell〉=
(setq ring-bell-function 'ignore
      visible-bell       nil)

(defun tess-ding () "Like `ding', but always makes a noise." (let ((visual-bell nil) (ring-bell-function nil)) (ding)))

always y-or-n

defalias yes-or-no-p〉=
(defalias 'yes-or-no-p 'y-or-n-p)

enable some emacs commands disabled by default

Enable disabled commands〉=
(mapc (lambda (sym)
        (put sym 'disabled nil))
      '(downcase-region erase-buffer eval-expression narrow-to-page
        narrow-to-region upcase-region))

Enable recursive minibuffers〉=
(setq enable-recursive-minibuffers t)

Enable recursive minibuffers〉=
(require 'mb-depth nil t)
(cond
 ((fboundp 'minibuffer-depth-indicate-mode)
  (minibuffer-depth-indicate-mode 1))
 ((fboundp 'minibuffer-indicate-depth-mode)
  (minibuffer-indicate-depth-mode 1)))

mb-depth fetch rule〉=
mb-depth.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/mb-depth.el

indent-tabs-mode

indent-tabs-mode〉=
(setq-default indent-tabs-mode nil)

editorconfig

editorconfig〉=
(autoload 'editorconfig-mode "editorconfig" nil t)
(autoload 'editorconfig-core-get-properties-hash "editorconfig-core")

(defun tess-enable-editorconfig-mode () (editorconfig-mode 1))

(add-hook 'tess-after-local-init-hook 'tess-enable-editorconfig-mode)

(setq editorconfig-mode-lighter " EC")

overwrite mode

disable overwrite-mode〉=
(put 'overwrite-mode 'disabled t)

defun tess-clear

defun tess-clear〉=
(defun tess-clear (&optional prefix)
  "Move the line containing point to the top of the window.
With PREFIX, move the line containing point to line PREFIX of the window."
  (interactive "P")
  (recenter (or prefix 0)))
(global-set-key (kbd "C-c c") 'tess-clear)

require final newline

require-final-newline〉=
(setq require-final-newline t)

inhibit default init〉=
(setq inhibit-default-init  t)

(defun tess-warn-about-default-init () (when (locate-library "default") (message "Warning: `default.el' not loaded") (sit-for 2)))

(add-hook 'tess-after-local-init-hook 'tess-warn-about-default-init)

sentence end double space

sentence-end-double-space〉=
(setq sentence-end-double-space nil)

(defvar tess-sentence-end-re "\(\w+\)\([.?!]\)\B" "Regular expression which matches potential sentence endings.")

(defvar tess-words-which-do-not-end-sentences '("Mr" "Mrs" "St") "Abbreviations which should not be considered to end sentences.")

(defun tess-sentence-end () "Returns the location of the next sentence-end in the current buffer. Resorts to `point-max' if it can't find a sentence end." (or (catch 'found (while (re-search-forward tess-sentence-end-re nil t) (when (or (member (match-string 2) '("?" "!")) (not (member (match-string 1) tess-words-which-do-not-end-sentences))) (throw 'found (point))))) (point-max)))

isearch

isearch highlight current match〉=
(setq search-highlight t)
(setq-default case-fold-search t)
(eval-after-load "isearch"
  '(define-key isearch-mode-map (kbd "C-h") 'isearch-mode-help))

isearch fg〉=
:foreground "〈light yellow〉"
isearch faces〉=
'(isearch ((t (〈cyan bg (alt)〉 〈isearch fg〉))))
'(isearch-lazy-highlight-face ((t (:background "〈dark green〉"
                                   〈isearch fg〉))))
'(lazy-highlight ((t (:background "〈medium red〉" 〈isearch fg〉))))
'(isearch-secondary ((t (:background "〈medium red〉" 〈isearch fg〉))))
'(isearch-fail ((t (:background "〈medium red〉" 〈isearch fg〉))))

tess-kill-mode-buffers

defun tess-kill-mode-buffers〉=
(defun tess-kill-mode-buffers (&optional mode)
  "Kill all buffers of this major mode.
With optional argument MODE, all buffers in major mode MODE are killed
instead."
  (interactive (list (when current-prefix-arg (tess-read-major-mode))))
  (setq mode (or mode major-mode))
  (when (or current-prefix-arg
            (y-or-n-p (format "Really kill all %s buffers? " mode)))
    (mapc (lambda (buffer)
            (when (with-current-buffer buffer
                    (eq major-mode mode))
              (kill-buffer buffer)))
          (buffer-list))))

some random eldoc hack

defun help-default-arg-highlight〉=
(defun help-default-arg-highlight (arg)
  "Upcase and fontify ARG for use with `eldoc-mode' and help."
  (propertize (upcase arg)
              'face 'font-lock-variable-name-face))
help faces〉=
'(help-argument-name ((t (〈variable face〉))))

uniquify

uniquify〉=
(when (ignore-errors (require 'uniquify))
  (setq-default uniquify-buffer-name-style 'forward))

timestamp

timestamp〉=
(add-hook 'write-file-hooks 'time-stamp)

organize buffer menu by major mode

Organize buffer menu by major mode〉=
(setq mouse-buffer-menu-mode-mult 1)

apropos do all

Apropos do all〉=
(setq apropos-do-all t)

truncate-lines

truncate-lines〉=
(setq truncate-partial-width-windows nil)

truncate-lines〉=
(setq-default truncate-lines t)

(defun tess-disable-truncate-lines () (setq truncate-lines nil))

(mapc (lambda (hook) (add-hook hook 'tess-disable-truncate-lines)) '(term-mode-hook eshell-mode-hook html-mode-hook))

kr-edit-region

edit region in a different major mode〉=
(defun kr-edit-region (&optional edit-mode)
  "Edit the current region in a separate buffer.
With a prefix arg, change `major-mode' to EDIT-MODE."
  (interactive (list (when current-prefix-arg (tess-read-major-mode))))
  (clone-indirect-buffer nil t)
  (narrow-to-region (region-beginning) (region-end))
  (shrink-window-if-larger-than-buffer)
  (when edit-mode (funcall edit-mode)))

defun tess-read-major-mode〉=
(defun tess-read-major-mode ()
  "Read a major mode from the user, and return it.
Based on Kevin Rogers' edit-region' interactive spec."   (intern (completing-read            (format "Major mode (default %s'): " major-mode)
           obarray 'kr-major-mode-p t nil nil
           (symbol-name major-mode))))

defun kr-major-mode-p〉=
(defun kr-major-mode-p (symbol)
  "Return non-nil if SYMBOL is a major mode.
Used in interactive' forms to read major mode names from the user."   (and (fboundp symbol)        (let ((function-name (symbol-name symbol)))          (and (string-match "-mode\\'" function-name)               (not (string-match "\\turn-\(on\|off\)-"
                                 function-name))))
       (not (assq symbol minor-mode-alist))))

auto-mode-case-fold

auto-mode-case-fold〉=
(setq auto-mode-case-fold t)

tess-find-mode

tess-find-mode〉=
(defun tess-find-mode (extension &optional interactive)
  "Returns the mode in which a file with EXTENSION would be opened."
  (interactive "sExtension: \np")
  (let ((mode (assoc-default (concat "." extension) auto-mode-alist
                             'string-match default-major-mode)))
    (when interactive
      (message "A file with extension .%s would be opened with mode %s"
               extension mode))
    mode))

custom autoload

defun custom-autoload〉=
(defun custom-autoload (symbol load)
  "Mark SYMBOL as autoloaded custom variable and add dependency LOAD."
  (put symbol 'custom-autoload t)
  (custom-add-load symbol load))
### Emacsclient
emacsclient (PowerShell)〉=
function Invoke-EmacsClient {
    Start-Process emacsclientw -Wait -ArgumentList @args
}
Set-Alias -Name emacsclient -Value Invoke-EmacsClient
defvar tess-server-emacs〉=
(defvar tess-server-emacs t
  "If non-null, this emacs should run an edit server.
By edit server, I mean the bit that emacsclient or gnuclient talk to.")

Choose which editor to use〉=
if command-recognized emacsclientw.exe; then
    alias emacsclient=emacsclienw.exe
fi
if command-recognized runemacs.exe; then
    alias emacs=runemacs.exe
fi
if command-recognized emacsclient; then
    export EDITOR='emacsclient'
elif command-recognized emacs; then
    export EDITOR='emacs'
else
    export EDITOR='vi'
fi
export VISUAL=$EDITOR
alias edit=$EDITOR

server-start〉=
(defun tess-start-server-if-wanted ()
  (when tess-server-emacs
    (server-start)))
(when (or (fboundp 'make-network-process)
          (file-executable-p (expand-file-name "emacsserver"
                                               exec-directory)))
  (add-hook 'tess-after-local-init-hook
            'tess-start-server-if-wanted))
emacs server〉=
(setq display-buffer-reuse-frames t)
〈server-start

archive-mode

archive-mode〉=
(add-to-list 'auto-mode-alist '("\\.egg\\'" . archive-mode))

Aquamacs

Machine Translation〉=
To illustrate the need for understanding in translation, a classic story
describes the machine translation of the phrase
    “The spirit is willing but the flesh is weak”
into Russian and back. The translation is said to have come out:
    “The vodka is strong but the meat is rotten.”

    — Strategies for Natural Language Processing,
      ed. Wendy Lehnert and Martin Ringle

Fix Viper under Aquamacs〉=
;; Fixes some kind of Viper/Aquamacs interaction issue
(raise-frame)
Disable Aquamacs' various bells and whistles〉=
(setq aquamacs-buffer-specific-frame-themes nil
      aquamacs-mode-specific-default-themes nil
      aquamacs-auto-frame-parameters-flag   nil
      special-display-buffer-names          nil
      special-display-regexps               nil)

(setq kill-emacs-query-functions (delq 'aquamacs-ask-to-save-options kill-emacs-query-functions))

vi and friends: nvi, vim, and Viper

Raised by wolves〉=
Me: Would anyone like the last cookie?
Nathan: I can't take the last cookie on principle.
Dave (reaching for cookie): I was raised by wolves!

vi

.exrc〉=
set autoindent
set shiftwidth=2

nvi

vim

Viper

Enable Viper in .emacs〉=
;; Enable Viper
;; (setq viper-mode t)
;; (add-hook 'tess-after-local-init-hook 'viper-mode)

Configure Viper's toggle key〉=
(setq viper-toggle-key (kbd "M-a"))

Ensure Viper doesn't mess with my cursor type〉=
(eval-after-load "viper-init"
  '(progn
     (mapc (lambda (hook)
             (remove-hook hook 'viper-restore-cursor-type))
           '(viper-vi-state-hook viper-replace-state-hook
             viper-emacs-state-hook))
     (remove-hook 'viper-insert-state-hook
                  'viper-set-insert-cursor-type)))

viper face variables〉=
'(viper-replace-overlay-cursor-color "〈cursor color (warning)〉")
'(viper-insert-state-cursor-color "〈cursor color (alt)〉")
'(viper-vi-state-cursor-color "〈cursor color〉")

viper faces〉=
'(viper-search-face ((t (〈cyan bg (alt)〉 〈isearch fg〉))))
'(viper-replace-overlay-face ((t (:foreground "〈dark black〉" :bold t
                                 :background "〈very light magenta〉"))))
'(viper-minibuffer-emacs-face ((t (:foreground "〈dark black〉"
                                  :background "DarkSeaGreen2"))))
'(viper-minibuffer-insert-face ((t (:foreground "〈dark black〉"
                                   :background "〈very light magenta〉"))))
'(viper-minibuffer-vi-face ((t (:foreground "〈dark black〉"
                               :background "〈light cyan〉"))))

.viper〉=
;;; .viper --- Theresa O'Connor's Viper configuration -- emacs-lisp --

Elisp Copyright Statement

;;; Code:

.viper〉=
(put 'viper-add-local-keys 'lisp-indent-function 1)

(setq viper-inhibit-startup-message t viper-expert-level 5 viper-electric-mode t viper-always t viper-want-ctl-h-help t viper-want-emacs-keys-in-insert t viper-want-emacs-keys-in-vi t viper-vi-style-in-minibuffer nil viper-no-multiple-ESC nil viper-keep-point-on-repeat nil viper-keep-point-on-undo t viper-case-fold-search t)

(setq-default viper-ex-style-editing nil viper-ex-style-motion nil viper-auto-indent t)

(when (fboundp 'viper-buffer-search-enable) (viper-buffer-search-enable))

.viper〉=
(when (featurep 'iswitchb)
  (setq viper-read-buffer-function 'iswitchb-read-buffer))

.viper〉=
(let ((open-entry (assoc "open" ex-token-alist)))
  (when (consp open-entry)
    (setcdr open-entry
            '((find-file (read-file-name "Find file: "))))))

.viper〉=
(when (boundp 'viper-insert-state-mode-list)
  (setq viper-insert-state-mode-list
        (delete 'sql-interactive-mode
                (delete 'eshell-mode
                        (delete 'inferior-lisp-mode
                                viper-insert-state-mode-list)))))

(when (boundp 'viper-emacs-state-mode-list) (mapc (lambda (mode) (add-to-list 'viper-emacs-state-mode-list mode)) '(cfengine-mode sql-interactive-mode eshell-mode inferior-lisp-mode inferior-python-mode rcirc-mode)))

.viper〉=
(when (boundp 'viper-insert-global-user-map)
  (define-key viper-insert-global-user-map (kbd "C-d") 'delete-char)
  (define-key viper-insert-global-user-map (kbd "C-v") 'scroll-up)
  (define-key viper-insert-global-user-map (kbd "C-\") 'toggle-input-method)
  (define-key viper-insert-global-user-map (kbd "C-t") 'transpose-chars)
  (define-key viper-insert-global-user-map (kbd "C-w") 'kill-region))

(when (boundp 'viper-vi-global-user-map) (define-key viper-insert-global-user-map (kbd "C-d") 'delete-char) (define-key viper-vi-global-user-map (kbd "C-u") 'universal-argument)

;; These are shockingly cool. (define-key viper-vi-global-user-map (kbd "q") 'fill-paragraph) (define-key viper-vi-global-user-map (kbd "t") 'transpose-chars)

(define-key viper-vi-global-user-map (kbd "C-v") 'scroll-up)

(define-key viper-vi-global-user-map (kbd "C-b") 'backward-char) (define-key viper-vi-global-user-map (kbd "C-f") 'forward-char) (define-key viper-vi-global-user-map (kbd "C-p") 'previous-line) (define-key viper-vi-global-user-map (kbd "C-n") 'next-line)

;; Being able to pull up help is a good thing. (define-key viper-vi-global-user-map (kbd "C-h") 'help-command)

;; I don't know what C-e or C-t do in vi by default and I don't care. (define-key viper-vi-global-user-map (kbd "C-e") 'viper-goto-eol) (define-key viper-vi-global-user-map (kbd "C-t") 'transpose-chars)

;; I don't need an alternate Meta key, thank you very much. (define-key viper-vi-global-user-map (kbd "C-\") 'toggle-input-method)

(define-key viper-vi-global-user-map (kbd "C-y") 'yank))

.viper〉=
(defun tess-viper-install-z-bindings ()
  (let ((zz-binding (key-binding (kbd "C-c C-c")))
        (zs-binding (key-binding (kbd "C-c C-s"))))
    ;; Ensure we have a local map to frob if need be
    (when (or zz-binding zs-binding)
      (unless (current-local-map)
        (use-local-map (make-sparse-keymap "Local map"))))
    (when zz-binding
      (viper-add-local-keys 'vi-state
        (list (cons "zz" zz-binding))))
    (when zs-binding
      (viper-add-local-keys 'vi-state
        (list (cons "zs" zs-binding))))))

(add-hook 'after-change-major-mode-hook 'tess-viper-install-z-bindings)

.viper〉=
(defun tess-disable-viper-auto-indent ()
  (when viper-mode
    (setq viper-auto-indent nil)))

(mapc (lambda (hook) (add-hook hook 'tess-disable-viper-auto-indent)) '(eshell-mode-hook nslookup-mode-hook wikipedia-mode-hook css-mode-hook))

.viper〉=
;;; .viper ends here

Email & Gnus

Gnus *Group* buffer looks〉=
(setq gnus-group-line-format
      ;; "%2{%M%S%p%} %0{%5y%} %P%1{%G%}\n"
      "%2{%p%M%} %P%1{%G%}: %0{%y%} %S\n")
(setq gnus-topic-line-format
      ;; "%i%3{[ %n -- %A ]%}%v\n"
      " %i%3{%n%}: %0{%A%}%v\n")

Gnus Summary buffer looks〉=
(setq gnus-summary-line-format
      "%U%R%z%{%B%} %0{%-25,25f %}%1{%s%}\n"
      ;; Remove [List] identifiers from subject lines
      gnus-list-identifiers
      '("^[^]]+[]]\s-"))

Disable displaying SVG in HTML emails〉=
(defun tess-disable-svg (orig-fun &optional type)
  (if (eq type 'svg)
      nil
    (funcall orig-fun type)))

(advice-add 'image-type-available-p :around #'tess-disable-svg)

my current primary email address〉=
hober0@gmail.com
user-mail-address〉=
(setq user-mail-address "〈my current primary email address〉"
      user-full-name    "Theresa O'Connor")
My email addresses〉=
'(;; Gmail
  "hober0@gmail.com"
  ;; Family domain
  "tess@oconnor.cx"
  "ted@oconnor.cx"
  ;; Work
  "hober@apple.com"
  "eoconnor@apple.com"
  ;; Old Teradata addresses
  "eo250006@teradata.com" "Edward.O'Connor@teradata.com"
  ;; Old EVDB / Eventful addresses
  "ted@evdb.com" "oconnor@evdb.com" "ted@eventful.com"
  ;; Old Tomo address
  "edward.oconnor@tomosoftware.com"
  ;; Old UCSD addresses
  "oconnor@ucsd.edu" "oconnor@soe.ucsd.edu"
  ;; RHIT
  "oconnoem@cs.rose-hulman.edu"
  "oconnoem@alumni.rose-hulman.edu"
  ;; old ISP
  "oconnoem@theworld.com")
mail-user-agent〉=
(setq mail-user-agent   'gnus-user-agent
      read-mail-command 'gnus)

Abbrevs in mail

Enable abbrevs〉=
(add-hook 'mail-setup-hook 'mail-abbrevs-setup)

Here's how to make Emacs take a \texttt{-gnus} argument which starts Gnus:

enable -gnus〉=
(add-to-list 'command-switch-alist
             '("gnus" . (lambda (&rest ignore)
                          (setq tess-server-emacs nil)
                          ;; Exit Emacs after quitting Gnus
                          (add-hook 'gnus-after-exiting-gnus-hook
                                    'save-buffers-kill-emacs)
                          ;; Start Gnus when Emacs starts
                          (add-hook 'tess-after-local-init-hook 'gnus t))))

Gnus Organization〉=
(setq message-user-organization "Church of Emacs")

Set ORGANIZATION〉=
export ORGANIZATION="Theresa O'Connor tess@oconnor.cx"

Sieve

sieve〉=
(when (locate-library "sieve-mode")
  (autoload 'sieve-mode "sieve-mode" nil t)
  (add-to-list 'auto-mode-alist
               '("\\.si\\(eve\\|v\\)\\'" . sieve-mode)))

Basic email look and feel〉=
(setq mail-signature t
      mail-yank-prefix "> "
      mail-from-style 'angles)

BBDB

bbdb faces〉=
'(bbdb-company ((t (:foreground "〈medium red〉"))))
'(bbdb-field-name ((t (〈keyword face〉))))
'(bbdb-field-value ((t (:foreground "〈light yellow〉"))))
'(bbdb-name ((t (:foreground "〈medium cyan〉"))))

The Insidious Big-Brother Database〉=
(when (require 'bbdb nil t)
  (setq bbdb-default-country nil
        bbdb-debug nil
        bbdb-file "~/.bbdb"
        bbdb-completion-display-record nil
        bbdb-quiet-about-name-mismatches 0)

(when (coding-system-p 'utf-8) (setq bbdb-file-coding-system 'utf-8)) (bbdb-initialize 'sendmail 'gnus 'message)

(when (fboundp 'eshell) (defun eshell/bbdb (regex) (bbdb regex nil)))

(add-hook 'message-setup-hook 'bbdb-define-all-aliases))

(defconst tess-bbdb-flag (featurep 'bbdb))

EUDC

EUDC〉=
(when (locate-library "eudc")
  (setq eudc-multiple-match-handling-method 'select)
  〈EUDC on macOS〉)

EUDC integration with the macOS' Contacts.app

EUDC ships with a backend that knows how to talk to macOS' Contacts.app, though it relies on a command-line utility that doesn't come with macOS or Emacs to work.

EUDC on macOS〉=
;; Only integrate with Contacts.app when the cli is installed
;;     https://github.com/shanecelis/contacts
(when (and (executable-find "contacts") (require 'eudcb-mab nil t))
  (add-to-list 'eudc-server-hotlist '("localhost" . mab)))

Gnus continued

shr config〉=
(setq shr-color-visible-distance-min 10
      shr-color-visible-luminance-min 60)
Gnus Authentication Sources〉=
;; (when (and (eq system-type 'darwin)
;;            (file-executable-p "/usr/bin/security"))
;;   (eval-after-load "auth-source"
;;     '(setq auth-sources
;;            (append (list 'macos-keychain-internet
;;                          'macos-keychain-generic)
;;                    auth-sources))))

gnus clone rule〉=
gnus/lisp/gnus.el:
        git clone http://git.gnus.org/gnus.git

bin/mimedown〉=
#!/usr/bin/env python3

mimedown - generate multipart text and HTML MIME message from Markdown input.

Requires mistune; install it with pip:

sudo -H python3 -m pip install mistune

import sys

import mistune

md2html = None if 'html' in dir(mistune): md2html = mistune.html elif 'markdown' in dir(mistune): md2html = mistune.markdown else: print("mistune install is broken", file=sys.stderr)

def mimedown(infile, outfile): text = infile.read() html = md2html(text) html = "%s" % html print('''<#multipart type=alternative> %s <#part type=text/html> %s <#/multipart> ''' % (text, html), file=outfile)

if name == 'main': mimedown(sys.stdin, sys.stdout)

mimedown command〉=
(defun tess-mimedown ()
  (interactive)
  (save-excursion
    (message-goto-body)
    (shell-command-on-region
     (point) (point-max) "~/bin/mimedown" nil t)))

Use open to preview PDFs on macOS〉=
(when (file-executable-p "/usr/bin/open")
  (eval-after-load "mailcap"
    '(mailcap-add "application/pdf" "open %s")))

I am not a Gnus novice any more〉=
(setq gnus-novice-user nil)

handle mailing lists nicely〉=
(setq gnus-add-to-list t
      message-subscribed-address-functions
      '(gnus-find-subscribed-addresses))

GCC header handling〉=
(setq gnus-gcc-mark-as-read t)

(defvar tess-default-gcc-group "INBOX")

(defun tess-gnus-message-archive-group (group) (setq group (or group tess-default-gcc-group "INBOX")) (let ((method (gnus-find-method-for-group group))) (format "%s+%s:%s" (car method) (cadr method) group)))

(setq gnus-message-archive-group 'tess-gnus-message-archive-group)

defun tess-gnus-mark-thread-advance〉=
(defun tess-gnus-mark-thread-advance (p)
  "Mark this thread, and advance point to the next one.
With prefix P, mark the next P threads, and advance point past all of them."
  (interactive "p")
  (let ((i 0))
    (while (< i p)
      (gnus-uu-mark-thread)
      (gnus-summary-next-thread 1)
      (setq i (+ i 1)))))

(add-hook 'gnus-summary-mode-hook (lambda () (local-set-key (kbd "") 'tess-gnus-mark-thread-advance)))

Edit Gnus score files as Gnus score files〉=
(add-to-list 'auto-mode-alist '("\.SCORE\'" . gnus-score-mode))

Ensure we load the right Gnus〉=
;; Let's make sure we load the right version of Gnus.
(ignore-errors (require 'gnus-load))
message-mail-alias-type〉=
(setq message-mail-alias-type
      (cond ((locate-library "ecomplete") 'ecomplete)
            (t 'mailabbrev)))

subject face〉=
:foreground "〈light yellow〉"
gnus faces〉=
'(gnus-cite-attribution-face ((t ())))
'(gnus-cite-attribution ((t ())))
'(gnus-cite-face-1 ((t (:foreground "〈light yellow〉"))))
'(gnus-cite-1 ((t (:foreground "〈light yellow〉"))))
'(gnus-cite-face-2 ((t (:foreground "〈medium yellow〉"))))
'(gnus-cite-2 ((t (:foreground "〈medium yellow〉"))))
'(gnus-cite-face-3 ((t (:foreground "〈medium cyan〉"))))
'(gnus-cite-3 ((t (:foreground "〈medium cyan〉"))))
'(gnus-cite-face-4 ((t (:foreground "〈medium red〉"))))
'(gnus-cite-4 ((t (:foreground "〈medium red〉"))))
'(gnus-cite-face-5 ((t (:foreground "〈light magenta〉"))))
'(gnus-cite-5 ((t (:foreground "〈light magenta〉"))))
'(gnus-cite-face-6 ((t (:foreground "〈medium green〉"))))
'(gnus-cite-6 ((t (:foreground "〈medium green〉"))))
'(gnus-cite-face-7 ((t (:foreground "〈medium blue〉"))))
'(gnus-cite-7 ((t (:foreground "〈medium blue〉"))))
'(gnus-cite-face-8 ((t (:foreground "〈dark white〉"))))
'(gnus-cite-8 ((t (:foreground "〈dark white〉"))))
'(gnus-cite-face-9 ((t (:foreground "〈dark cyan〉"))))
'(gnus-cite-9 ((t (:foreground "〈dark cyan〉"))))
'(gnus-cite-face-10 ((t (:foreground "〈light yellow〉"))))
'(gnus-cite-10 ((t (:foreground "〈light yellow〉"))))
'(gnus-cite-face-11 ((t (:foreground "〈medium yellow〉"))))
'(gnus-cite-11 ((t (:foreground "〈medium yellow〉"))))

gnus faces〉=
'(gnus-emphasis-bold ((t (:bold t))))
'(gnus-emphasis-bold-italic ((t (:italic t :bold t))))
'(gnus-emphasis-italic ((t (:italic t))))
'(gnus-emphasis-underline ((t (:underline t))))
'(gnus-emphasis-underline-bold ((t (:bold t :underline t))))
'(gnus-emphasis-underline-bold-italic ((t (:italic t :bold t :underline t))))
'(gnus-emphasis-underline-italic ((t (:italic t :underline t))))

gnus faces〉=
'(gnus-group-news-1 ((t ())))
'(gnus-group-news-2 ((t ())))
'(gnus-group-news-3 ((t ())))
'(gnus-group-news-4 ((t ())))
'(gnus-group-news-5 ((t ())))
'(gnus-group-news-6 ((t ())))
'(gnus-group-news-low ((t ())))
'(gnus-group-mail-1 ((t ())))
'(gnus-group-mail-2 ((t ())))
'(gnus-group-mail-3 ((t ())))
'(gnus-group-mail-4 ((t ())))
'(gnus-group-mail-5 ((t ())))
'(gnus-group-mail-6 ((t ())))
'(gnus-group-mail-low ((t ())))

gnus faces〉=
(gnus-header-content-face ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) (gnus-header-content ((t 〈dim this face when appropriate〉)))
'(gnus-header-from-face ((t (:foreground "DarkSeaGreen2"))))
'(gnus-header-from ((t (:foreground "DarkSeaGreen2"))))
'(gnus-header-name-face ((t (:foreground "〈medium cyan〉"))))
'(gnus-header-name ((t (:foreground "〈medium cyan〉"))))
'(gnus-header-newsgroups-face ((t (:foreground "〈medium green〉"))))
'(gnus-header-newsgroups ((t (:foreground "〈medium green〉"))))
'(gnus-header-subject-face ((t (〈subject face〉))))
'(gnus-header-subject ((t (〈subject face〉))))
(gnus-signature-face ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) (gnus-signature ((t 〈dim this face when appropriate〉)))
'(gnus-summary-cancelled-face ((t (:foreground "〈medium yellow〉"))))
'(gnus-summary-cancelled ((t (:foreground "〈medium yellow〉"))))
'(gnus-summary-high-read-face ((t (:foreground "〈medium yellow〉"))))
'(gnus-summary-high-read ((t (:foreground "〈medium yellow〉"))))
'(gnus-summary-high-ticked-face ((t (:foreground "〈medium red〉"))))
'(gnus-summary-high-ticked ((t (:foreground "〈medium red〉"))))
'(gnus-summary-normal-ticked-face ((t (:foreground "〈light red〉"))))
'(gnus-summary-normal-ticked ((t (:foreground "〈light red〉"))))
'(gnus-summary-low-read-face ((t (:foreground "〈medium yellow〉"))))
'(gnus-summary-low-read ((t (:foreground "〈medium yellow〉"))))
'(gnus-summary-selected-face ((t (〈default (alt)〉))))
'(gnus-summary-selected ((t (〈default (alt)〉))))

Messages

abbrev-definitions〉=
(define-abbrev-table 'message-mode-abbrev-table '(
    ("pnc" "Privileged & Confidential" nil 0)
    ))

mm faces〉=
'(mm-uu-extract ((t (:background "〈dark black (alt)〉"
                     :foreground "〈light white〉"))))

message faces〉=
'(message-cited-text-face ((t (:foreground "〈medium red〉"))))
'(message-cited-text ((t (:foreground "〈medium red〉"))))

message faces〉=
'(message-header-cc-face ((t (:foreground "〈medium green〉"))))
'(message-header-cc ((t (:foreground "〈medium green〉"))))
'(message-header-name-face ((t (:foreground "〈medium green〉"))))
'(message-header-name ((t (:foreground "〈medium green〉"))))
'(message-header-newsgroups-face ((t (:foreground "〈medium green〉"))))
'(message-header-newsgroups ((t (:foreground "〈medium green〉"))))
'(message-header-other-face ((t (:foreground "〈medium cyan〉"))))
'(message-header-other ((t (:foreground "〈medium cyan〉"))))
'(message-header-subject-face ((t (〈subject face〉))))
'(message-header-subject ((t (〈subject face〉))))
'(message-header-to-face ((t (:foreground "〈medium cyan〉"))))
'(message-header-to ((t (:foreground "〈medium cyan〉"))))
'(message-header-xheader-face ((t (:foreground "〈medium cyan〉"))))
'(message-header-xheader ((t (:foreground "〈medium cyan〉"))))

message faces〉=
'(message-mml-face ((t (:foreground "〈medium green〉"))))
'(message-mml ((t (:foreground "〈medium green〉"))))
'(message-separator-face ((t (〈error face〉))))
'(message-separator ((t (〈error face〉))))

Strong Bad email deletion〉=
(defun tess-insert-centered-line (line)
  "Insert LINE into the current buffer.
Will also insert the necessary number of spaces and newlines to center
LINE in the window."
  (let ((lines (make-string (/ (frame-height) 2) ?\n))
        (spaces (make-string (- (/ (frame-width) 2)
                                (/ (length line) 2))
                             ?\ )))
    (insert lines spaces line)))

(defmacro with-compy-deleted-display (&rest body) "Execute forms in BODY while displaying a 'DELETED!!' buffer. Just like on Strong Bad's Compy 386. BA-LEETED!" `(save-window-excursion (let ((old-buf (current-buffer))) (with-temp-buffer (setq mode-line-format nil indicate-empty-lines nil indicate-buffer-boundaries nil) (let ((default-bg (face-background 'default)) (default-fg (face-foreground 'default)) (fringe-bg (face-background 'fringe)) (fringe-fg (face-foreground 'fringe))) (unwind-protect (progn (set-face-background 'default "Medium Blue") (set-face-foreground 'default "White") (set-face-background 'fringe "Medium Blue") (set-face-foreground 'fringe "White") (tess-insert-centered-line "DELETED!!!") (message "") (delete-other-windows) (switch-to-buffer (current-buffer)) (recenter) (with-current-buffer old-buf ,@body)) (set-face-background 'default default-bg) (set-face-foreground 'default default-fg) (set-face-background 'fringe fringe-bg) (set-face-foreground 'fringe fringe-fg))))))) (put 'with-compy-deleted-display 'lisp-indent-function 0)

;; (defadvice gnus-summary-delete-article (around compyify-deletion activate) ;; "Ensure that article deletion always looks like Strong Bad's Compy 386." ;; (with-compy-deleted-display ;; (sit-for 1) ;; ad-do-it))

SMTP

SMTP handling〉=
(defvar tess-smtp-flag t
  "*Non-nil if I should use SMTP for sending mail.
Set this before loading ~/.gnus!")

SMTP handling〉=
(when tess-smtp-flag
  (setq message-send-mail-function 'smtpmail-send-it
        send-mail-function         'smtpmail-send-it
        smtpmail-local-domain      nil
        smtpmail-debug-info        t))

Gnus SMTP config〉=
(setq smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
      smtpmail-smtp-server "smtp.gmail.com"
      smtpmail-default-smtp-server "smtp.gmail.com"
      send-mail-function 'smtpmail-send-it
      message-send-mail-function 'smtpmail-send-it
      smtpmail-smtp-service 587
      smtpmail-auth-credentials "~/.authinfo")

Configure gnus-face-N〉=
(setq gnus-face-0 'font-lock-type-face)
(setq gnus-face-1 'font-lock-string-face)
(setq gnus-face-2 'font-lock-variable-name-face)
(setq gnus-face-3 'font-lock-keyword-face)

Visible headers〉=
(eval-after-load "gnus-art"
  '(setq gnus-visible-headers
         (concat (format
                  "^\(%s\):"
                  (regexp-opt '("User-Agent" "X-Bugzilla-Component"
                                ;; "X-Mailer"
                                "X-Newsreader" "X-Spam-Level"
                                "List-Id" "X-Report-Spam" "Archived-At"
                                "Comments" "Message-Id")))
                 "\|" gnus-visible-headers)))

Article headers〉=
Visible headers

(defun tess-save-message-url-to-kill-ring () "Copy a message: URL to the current article." (interactive) (save-excursion (gnus-with-article-headers (gnus-article-goto-header "Message-Id") (let ((mid (buffer-substring-no-properties (1+ (point)) (line-end-position)))) (kill-new (concat "message:" (url-hexify-string mid)))))))

Gnus Organization〉 (setq gnus-treat-hide-headers 'head gnus-treat-hide-boring-headers 'head message-default-headers mail-default-headers)

spam reporting〉=
(defun tess-report-spam ()
  "Blah blah blah."
  (interactive)
  (let* ((server-name
          (gnus-method-to-server-name
           (gnus-find-method-for-group gnus-newsgroup-name)))
         (reporting-function (cdr (assoc server-name tess-report-spam-map))))
    (if reporting-function
        (funcall reporting-function)
      (message "No suitable spam reporting mechanism found."))))

;; S x and M-d for reporting spam from the Summary buffer (gnus-define-keys gnus-summary-mode-map "Sx" tess-report-spam "\M-d" tess-report-spam)

(defvar tess-report-spam-map '(("nnimap+imap.gmail.com" . tess-report-spam-to-gmail) ("nntp+news.gmane.org" . tess-report-spam-to-gmane)) "Blah blah blah.")

(defun tess-report-spam-to-gmail () (gnus-summary-move-article nil "nnimap+imap.gmail.com:[Gmail]/Spam"))

(autoload 'url-retrieve "url")

(defun tess-report-spam-to-gmane () (gnus-with-article-headers (gnus-article-goto-header "Archived-At") (let ((url (buffer-substring-no-properties (+ 2 (point)) (1- (line-end-position)))) (url-request-method "POST")) ;; Every so often, gmane articles don't have Archived-At headers. (when (string-match gnus-button-url-regexp url) ;; N.B., we replace either 'article' or 'permalink' so that this ;; doesn't depend on my s/permalink/article/ hack. (setq url (replace-regexp-in-string "\(article\|permalink\)" "spam" url nil t)) (setq url (replace-regexp-in-string "/\([[:digit:]]+\)$" ; $ ":\1:unconfirmed" url)) ;; Fire and forget the spam report. (url-retrieve url (lambda (&rest ignore) (message "Spam reported to Gmane.")))))))

tc.el fetch rule〉=
tc.el:
        curl -O http://shasta.cs.uiuc.edu/~lrclause/tc.el
Trivial Cite〉=
(autoload 'trivial-cite "tc" nil t)
(setq message-cite-function 'trivial-cite
      tc-make-attribution   'tc-tiny-attribution)
tess-insert-citation-line〉=
(defun tess-insert-citation-line ()
  "Insert a simple citation line."
  (when message-reply-headers
    (let* ((components (mail-extract-address-components
                        (mail-header-from message-reply-headers)))
           (name (car (split-string (or (car components) "You"))))
           (email (cadr components))
           (citing-self
            (string-match gnus-ignored-from-addresses email)))
      (insert "Hi")
      (when (and (not citing-self)
                 (not (string-equal name "You")))
        (insert " " name))
      (insert ",\n\n")
      (insert (if citing-self "I" "You") " wrote:\n\n"))))

(setq message-citation-line-function 'tess-insert-citation-line)

tess-insert-citation-line〉=
(defun tess-fixup-multireply-attributions (start end)
  (interactive "r")
  (goto-char start)
  (while (re-search-forward
          "^\(Hi \(\w+\),\n\n\)\(You\) wrote:$" end t) ; $
    (replace-match "\2" nil nil nil 3)
    (replace-match "" nil nil nil 1)))

(defun tess-fixup-multireply () (interactive) (save-excursion (message-goto-body) (insert "Hi all,\n\n") (tess-fixup-multireply-attributions (point) (point-max))))

SuperCite〉=
(add-hook 'mail-citation-hook 'sc-cite-original)
(setq news-reply-header-hook nil)
(setq sc-auto-fill-region-p nil
      sc-citation-leader " ")
(when tess-bbdb-flag
  (require 'bbdb-sc)
  (bbdb-initialize 'sc)
  (setq sc-preferred-attribution-list
        '("sc-lastchoice" "x-attribution" "sc-consult"
          "initials" "firstname" "lastname"))
  (add-to-list 'sc-attrib-selection-list
               '("sc-from-address"
                 ((".*" . (bbdb/sc-consult-attr
                           (sc-mail-field "sc-from-address"))))))
  (let ((cell (assoc "^\'" sc-mail-glom-frame)))
    (when cell
      (setcdr cell
              '((progn (bbdb/sc-default)
                       (list 'abort '(step . 0))))))))
Choosing which citation code to use〉=
(when (locate-library "tc")
  〈Trivial Cite〉)

boxquote.el fetch rule〉=
boxquote.el:
        curl -O http://www.davep.org/emacs/boxquote.el
boxquote〉=
(when (locate-library "boxquote")
  (defvar tess-boxquote-map (make-sparse-keymap))
  (global-set-key (kbd "C-c q") tess-boxquote-map)
  (mapc (lambda (cons)
          (let ((command (car cons))
                (key (cdr cons)))
            (autoload command "boxquote" nil t)
            (define-key tess-boxquote-map key command)))
        '((boxquote-region            . "r")
          (boxquote-buffer            . "b")
          (boxquote-insert-file       . "i")
          (boxquote-yank              . "y")
          (boxquote-defun             . "F")
          (boxquote-paragraph         . "p")
          (boxquote-describe-function . "f")
          (boxquote-describe-variable . "v")
          (boxquote-describe-key      . "k")
          (boxquote-kill              . "K")
          (boxquote-unbox             . "u"))))

override gnus-goto-colon〉=
(defun gnus-goto-colon ()
  (goto-char (point-at-bol)))

gnus-ignored-from-addresses〉=
(setq gnus-ignored-from-addresses
      (regexp-opt 〈My email addresses〉))
;; why isn't this the default?
(setq message-dont-reply-to-names
      gnus-ignored-from-addresses)

configure gnus verbosity〉=
(setq gnus-verbose          1
      gnus-verbose-backends 1)

use message-forward-subject-fwd if available〉=
(when (fboundp 'message-forward-subject-fwd)
  (setq message-make-forward-subject-function 'message-forward-subject-fwd))

nnfolder configuration〉=
(add-hook 'nnfolder-save-buffer-hook
          (lambda ()
            (set (make-local-variable 'backup-inhibited) t)))

nnmail configuration〉=
(setq nnmail-split-methods 'nnmail-split-fancy)

(setq nnmail-treat-duplicates 'warn ; or 'delete nnmail-cache-accepted-message-ids t nnmail-message-id-cache-length 10000)

disable killing of groups by mistake〉=
(eval-after-load "gnus-group"
  '(define-key gnus-group-mode-map (kbd "C-k") nil))
(eval-after-load "gnus-topic"
  '(define-key gnus-topic-mode-map (kbd "C-k") nil))

disable indenting of topics by mistake〉=
(eval-after-load "gnus-topic"
  '(define-key gnus-topic-mode-map (kbd "TAB") nil))

gnus topic configuration〉=
(setq gnus-topic-display-empty-topics t)

; Don't display topics that have nothing in them (setq gnus-topic-display-empty-topics nil)

gnus subscribe randomly〉=
(when (fboundp 'gnus-subscribe-randomly)
  (if (listp gnus-subscribe-newsgroup-method)
      (add-to-list 'gnus-subscribe-newsgroup-method
                   'gnus-subscribe-randomly)
    (if (null gnus-subscribe-newsgroup-method)
        (setq gnus-subscribe-newsgroup-method 'gnus-subscribe-randomly)
      (setq gnus-subscribe-newsgroup-method
            (list 'gnus-subscribe-randomly
                  gnus-subscribe-newsgroup-method)))))

key binding for gnus-group-mail〉=
(global-set-key (kbd "C-x m") 'gnus-group-mail)

tess typo gnus key bindings〉=
;; I always hit 'j' instead of 'n'
(gnus-define-keys gnus-summary-mode-map
  "j" gnus-summary-next-unread-article)

scoring in gnus〉=
(add-hook 'gnus-summary-mode-hook
          (lambda ()
            (setq gnus-summary-expunge-below -5)))

(add-hook 'message-sent-hook 'gnus-score-followup-thread)

enable gnus topic mode〉=
(add-hook 'gnus-group-mode-hook 'gnus-topic-mode)

gnus topic mode keybindings〉=
(eval-after-load "gnus-topic"
  ;; Disable TAB
  '(define-key gnus-topic-mode-map [tab] nil))

misc gnus settings〉=
(setq mail-source-delete-incoming           t
      gnus-activate-foreign-newsgroups      nil
      gnus-treat-display-smileys            nil
      gnus-treat-strip-trailing-blank-lines t
      gnus-treat-hide-citation              nil
      gnus-treat-strip-multiple-blank-lines nil
      gnus-inhibit-startup-message          t
      ;; My scores should be global.
      gnus-home-score-file                  "all.SCORE"
      gnus-visual                           t)

fix dumb quotes in Gnus〉=
; Change a \205 figure to "..."
(add-hook 'gnus-part-display-hook 'article-treat-dumbquotes)

Gnus select methods〉=
(defvar tess-has-configured-gnus nil)

(unless tess-has-configured-gnus 〈Gnus SMTP config〉 (setq gnus-select-method '(nnimap "imap.gmail.com" (nnimap-stream ssl) (nnimap-authenticator login)) gnus-secondary-select-methods '((nntp "news.gmane.org") (nntp "news.eternal-september.net")) tess-has-configured-gnus t))

Gmane special-handling〉=
(defun tess-mangle-gmane-archival-gnus-data (link)
  "Mangle the `gnus-data' property value LINK.
Specifically, change the archival URL from permalink.gmane.org (Gmane's
blog-like interface) to article.gmane.org (Gmane's newslike interface)."
  (let ((original-date (get-text-property 5 'original-date link))
        (face (get-text-property 5 'face link)))
    (propertize (replace-regexp-in-string "permalink.gmane.org"
                                          "article.gmane.org"
                                          (substring-no-properties link))
                'face face 'original-date original-date)))

(defun tess-mangle-gmane-archival-header () "Mangle Gmane's Archived-At header to be more useful. Specifically, change the archival URL from permalink.gmane.org (Gmane's blog-like interface) to article.gmane.org (Gmane's newslike interface)." (gnus-with-article-headers (when (gnus-article-goto-header "Archived-At") (save-excursion (alter-text-property (+ 2 (point)) (1- (line-end-position)) 'gnus-data 'tess-mangle-gmane-archival-gnus-data)) (when (re-search-forward "permalink.gmane.org" (line-end-position) t) (replace-match (propertize "article.gmane.org" 'face 'gnus-header-content))))))

(add-hook 'gnus-article-prepare-hook 'tess-mangle-gmane-archival-header)

Gnus posting styles〉=
(unless tess-has-configured-gnus
  (setq gnus-posting-styles
        '((".*"
           (name "Theresa O'Connor")
           ("Jabber-ID" "hober0@gmail.com")
           ("X-Attribution" "Tess")
           (address "〈my current primary email address〉")
           (signature "
Theresa O'Connor 〈my current primary email address

Ense petit placidam sub libertate quietem.") (organization nil)))));%

Cleaning up mailing list email〉=
(defun tess-gnus-article-treat-alexmog ()
  "Clean up alexmog's idiosyncratic quoting style."
  (save-excursion
    (when (article-goto-body)
      (let ((inhibit-read-only t))
        (while (re-search-forward "^±" nil t)
          (replace-match ">"))))))

(eval-after-load "gnus-art" '(add-hook 'gnus-part-display-hook 'tess-gnus-article-treat-alexmog))

Reading W3C and WHATWG mailing list archives in Gnus〉=
(require 'calendar) ;; calendar-month-name-array

(autoload 'article-goto-body "gnus-art") (autoload 'format-spec "format-spec") (autoload 'gnus-group-read-ephemeral-group "gnus-group") (autoload 'mm-make-temp-file "mm-util") (autoload 'url-file-nondirectory "url-util")

;; Archives

(defvar tess-w3c-lists '("member-webapps" "public-canvas-api" "public-css-testsuite" "public-fx" "public-html" "public-html-a11y" "public-html-bugzilla" "public-html-comments" "public-html-data-tf" "public-html-wg-announce" "public-html-xml" "public-identity" "public-ietf-w3c" "public-iri" "public-script-coord" "public-tracking" "public-web-security" "public-webapps" "public-web-notification" "team-html-editors" "uri" "w3c-css-wg" "websec" "www-archive" "www-dom" "www-html" "www-style" "www-tag") "Mailing lists that I'm subscribed to over at w3.org.")

(defun tess-generate-w3c-archive-url (mailing-list year month) "Returns the URL for MAILING-LIST's archive mbox for YEAR and MONTH." (format-spec "https://lists.w3.org/Archives/Public/%l/mboxes/%Y-%m.mbx" (list (cons ?l mailing-list) (cons ?Y (format "%04d" year)) (cons ?m (format "%02d" month)))))

(defun tess-read-year-month () (let ((today (decode-time))) (list (read-number "Year: " (nth 5 today)) (completing-read "Month: " (append calendar-month-name-array nil) nil nil (elt calendar-month-name-array (1- (nth 4 today)))))))

(defun tess-read-w3c-archive (mailing-list year month) "Read the archive for MAILING LIST of YEAR and MONTH. Based on gnus-read-ephemeral-gmane-group' from gnus-group.el." (interactive (let ((today (decode-time))) (append (list (completing-read "Mailing list: " tess-w3c-lists)) (tess-read-year-month)))) (when (stringp month) (setq month (1+ (position month calendar-month-name-array :test 'string-equal)))) (let* ((url (tess-generate-w3c-archive-url mailing-list year month)) (filename (concat mailing-list "_" (url-file-nondirectory url))) (tmpfile (mm-make-temp-file filename))) (with-temp-file tmpfile (url-insert-file-contents url) (write-region (point-min) (point-max) tmpfile) (gnus-group-read-ephemeral-group filename (nndoc ,tmpfile (nndoc-article-type mbox)))) (delete-file tmpfile)))

(defun tess-whatwg-year-month (year month) (format-spec "%Y-%m" (list (cons ?Y (format "%04d" year)) (cons ?m month))))

(defun tess-whatwg-archive-filename (year month) (mm-make-temp-file (format "whatwg-%s" (tess-whatwg-year-month year month)) nil ".mbox.gz"))

(defun tess-generate-whatwg-archive-url (year month) "Returns the URL for the WHATWG's archive mbox for YEAR and MONTH." (format "http://lists.whatwg.org/pipermail/whatwg-whatwg.org/%s.txt.gz" (tess-whatwg-year-month year month)))

(defun tess-read-whatwg-archive (year month) "Read the WHATWG archive of YEAR and MONTH. Based on gnus-read-ephemeral-gmane-group' from gnus-group.el." (interactive (tess-read-year-month)) (let* ((url (tess-generate-whatwg-archive-url year month)) (groupname (format "whatwg-%s" (tess-whatwg-year-month year month))) (tmpfile (tess-whatwg-archive-filename year month)) (coding-system-for-write 'no-conversion) (jka-compr-inhibit t)) (with-temp-file tmpfile (url-insert-file-contents url)) (shell-command (format "gzip -d %s" tmpfile)) (gnus-group-read-ephemeral-group groupname (nndoc ,(substring tmpfile 0 -3) (nndoc-article-type mbox))) (delete-file tmpfile)))

IRC

I used to be one of the maintainers of ERC, one of the IRC clients included with Emacs by default.

ERC

tracking.el fetch rule〉=
tracking.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/tracking.el
erc-robot.el fetch rule〉=
erc-robot.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/erc-robot.el

ERC, an Emacs IRC Client〉=
(autoload 'erc "erc" nil t)
(autoload 'erc-select "erc" nil t)
(autoload 'erc-select-ssl "erc" nil t)

ERC, an Emacs IRC Client〉=
(setq erc-server                         "irc.w3.org"
      erc-port                           6665
      erc-user-full-name                 "Theresa O'Connor"
      erc-email-userid                   "tess"
      erc-nick                           '("hober" "hober2" "hober3")
      erc-nicklist-use-icons             nil
      erc-password                       nil ; set this in local config
      erc-nickserv-passwords             nil ; set this in local config
      erc-anonymous-login                t
      erc-auto-query                     'bury
      erc-join-buffer                    'bury
      erc-max-buffer-size                30000
      erc-prompt-for-password            nil
      erc-prompt-for-nickserv-password   nil
      erc-command-indicator              "CMD"
      erc-echo-notices-in-current-buffer t
      erc-send-whitespace-lines          nil
      erc-hide-list                      '("JOIN" "PART" "QUIT")
      erc-ignore-list                    '("jibot")
      erc-autojoin-timing                'ident
      erc-autojoin-delay                 30
      erc-autojoin-channels-alist        '())

ERC, an Emacs IRC Client〉=
(setq erc-quit-reason-various-alist
      '(("brb"    "I'll be right back.")
        ("lunch"  "Having lunch.")
        ("dinner" "Having dinner.")
        ("food"   "Getting food.")
        ("sleep"  "Sleeping.")
        ("work"   "Getting work done.")
        (".*"     (yow))))

(setq erc-part-reason-various-alist erc-quit-reason-various-alist erc-part-reason 'erc-part-reason-various erc-quit-reason 'erc-quit-reason-various)

ERC, an Emacs IRC Client〉=
(defvar tess-erc-autojoin t
  "Whether or not ERC should autojoin on connect.")

(defvar tess-erc-identify t "Whether or not ERC should identify with NickServ on connect.")

(setq erc-server-alist '(("w3c" w3c "irc.w3.org" 6665)) erc-networks-alist '((w3c "w3.org")))

(defvar tess-erc-default-network "w3c" "Which IRC network to connect to by default.")

(defun tess-erc-nick () (cond ((listp erc-nick) (car erc-nick)) ((stringp erc-nick) erc-nick) (t "hober")))

(defun tess-irc-server-uses-ssl-p (server) "If non-null, SERVER requires SSL." (eq server 'apple))

(defun tess-irc (netspec) "Interactively select an IRC network to connect to. Loosely based on `erc-server-select'." (interactive (list (assoc (completing-read (format "IRC network (default %s)? " tess-erc-default-network) erc-server-alist nil t nil nil tess-erc-default-network) erc-server-alist))) (let* ((network (nth 1 netspec)) (nick (tess-erc-nick)) (args (list :server (nth 2 netspec) :port (nth 3 netspec) :nick nick)) (password (cdr (assoc nick (cadr (assoc network erc-nickserv-passwords)))))) (when password (setq args (append (list :password password) args))) (setq tess-erc-identify (not (eq network 'freenode))) ;; setq not let because of dumb reasons (setq erc-server-connect-function (if (tess-irc-server-uses-ssl-p network) 'erc-open-tls-stream 'open-network-stream)) (apply 'erc args)))

erc face variables〉=
;; '(erc-button-nickname-face 'underline)

erc faces〉=
'(erc-action-face ((t (:bold t))))
'(erc-bold-face ((t (:bold t))))
'(erc-command-indicator-face ((t (:bold t))))
'(erc-current-nick-face ((t (:foreground "〈light cyan〉"))))
'(erc-my-nick-face ((t (:foreground "#fd9ef1223e85"))))
'(erc-default-face ((t ())))
'(erc-direct-msg-face ((t (:foreground "〈medium cyan〉"))))
'(erc-error-face ((t (〈error face〉))))
`(erc-fool-face ((t 〈dim this face when appropriate〉)))
'(erc-input-face ((t (:foreground "〈light yellow〉"))))
'(erc-inverse-face ((t (:inverse-video t))))
'(erc-keyword-face ((t (:foreground "〈medium magenta〉" :bold t))))
'(erc-nick-default-face ((t (:foreground "〈medium cyan〉"))))
'(erc-nick-msg-face ((t (:foreground "〈light magenta〉" :bold t))))
'(erc-notice-face ((t (:foreground "〈dark cyan〉"))))
'(erc-pal-face ((t (:foreground "〈medium yellow〉"))))
'(erc-prompt-face ((t (〈prompt face〉))))
'(erc-timestamp-face ((t (:foreground "〈medium green〉"))))
'(erc-underline-face ((t (:underline t))))

erc ansi bg faces〉=
'(bg:erc-color-face0 ((t (:background "〈medium white〉"))))
'(bg:erc-color-face1 ((t (:background "〈medium black〉"))))
'(bg:erc-color-face2 ((t (:background "〈dark blue〉"))))
'(bg:erc-color-face3 ((t (:background "〈dark green〉"))))
'(bg:erc-color-face4 ((t (:background "〈medium red〉"))))
'(bg:erc-color-face5 ((t (:background "〈dark yellow〉"))))
'(bg:erc-color-face6 ((t (:background "〈medium magenta〉"))))
'(bg:erc-color-face7 ((t (:background "〈dark red〉"))))
'(bg:erc-color-face8 ((t (:background "〈light yellow〉"))))
'(bg:erc-color-face9 ((t (:background "〈medium green〉"))))
'(bg:erc-color-face10 ((t (:background "〈medium blue〉"))))
'(bg:erc-color-face11 ((t (:background "〈medium cyan〉"))))
'(bg:erc-color-face12 ((t (:background "〈dark cyan〉"))))
'(bg:erc-color-face13 ((t (:background "〈light magenta〉"))))
'(bg:erc-color-face14 ((t (:background "gray50"))))
'(bg:erc-color-face15 ((t (:background "gray90"))))

erc ansi fg faces〉=
'(fg:erc-color-face0 ((t (〈default fg〉))))
'(fg:erc-color-face1 ((t (:foreground "〈medium black〉"))))
'(fg:erc-color-face2 ((t (:foreground "〈dark blue〉"))))
'(fg:erc-color-face3 ((t (:foreground "〈dark green〉"))))
'(fg:erc-color-face4 ((t (:foreground "〈medium red〉"))))
'(fg:erc-color-face5 ((t (:foreground "〈dark yellow〉"))))
'(fg:erc-color-face6 ((t (:foreground "〈medium magenta〉"))))
'(fg:erc-color-face7 ((t (:foreground "〈dark red〉"))))
'(fg:erc-color-face8 ((t (:foreground "〈light yellow〉"))))
'(fg:erc-color-face9 ((t (:foreground "〈medium green〉"))))
'(fg:erc-color-face10 ((t (:foreground "〈medium blue〉"))))
'(fg:erc-color-face11 ((t (:foreground "〈medium cyan〉"))))
'(fg:erc-color-face12 ((t (:foreground "〈dark cyan〉"))))
'(fg:erc-color-face13 ((t (:foreground "〈light magenta〉"))))
'(fg:erc-color-face14 ((t (:foreground "gray50"))))
'(fg:erc-color-face15 ((t (:foreground "gray90"))))

.ercrc.el〉=
;;; .ercrc.el --- Theresa O'Connor's ERC configuration -- emacs-lisp --

Elisp Copyright Statement

;;; Code:

.ercrc.el〉=
(setq erc-header-line-uses-help-echo-p nil
      ;; Just the topic, ma'am.
      erc-header-line-format "%o")

.ercrc.el〉=
(require 'erc-join nil t)

(add-to-list 'erc-autojoin-channels-alist '(".*w3.org" "#ac" "#ac-chat" "#bad-attitude" "#css" "#editing" "#epub" "#houdini" "#html-wg" "#mediawg" "#privacycg" "#pwe" "#sysreq" "#web-adv" "#webapps" "#webrtc" "#webscreens" "#wicg" "#wpwg" "#zami"))

.ercrc.el〉=
(require 'erc-services nil t)
(when tess-erc-identify ; Defined in .emacs
  (erc-nickserv-mode 1)
  (erc-services-mode 1))

.ercrc.el〉=
(defun tess-erc-spc-dwim ()
  "DWIMmy behavior for the SPC key in ERC."
  (interactive)
  (condition-case nil (insert " ")
    (text-read-only
     (condition-case nil (scroll-up)
       (end-of-buffer (recenter 0))))))

(eval-after-load "erc" '(define-key erc-mode-map (kbd "SPC") 'tess-erc-spc-dwim))

.ercrc.el〉=
(cond ((require 'erc-hl-nicks nil t)
       (erc-hl-nicks-mode 1))
      ((require 'erc-highlight-nicknames nil t)
       (erc-highlight-nicknames-mode 1)))

erc faces〉=
'(erc-highlight-nick-base-face ((t ())))
'(erc-hl-nicks-nick-base-face ((t ())))

erc-highlight-nicknames.el fetch rule〉=
erc-highlight-nicknames.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/erc-highlight-nicknames.el
erc-hl-nicks.el:
        curl -O $(GITHUB)/leathekd/erc-hl-nicks/master/erc-hl-nicks.el

.ercrc.el〉=
(require 'erc-match)
(erc-match-mode 1)
(setq erc-pals nil
      erc-fools '(;; bots
                  "\bcchelpbot\b" "\bCIA-47\b" "\bfsbot\b"
                  "\bjibot\b" "\bmfbot\b" "\bpimpbot\b"
                  "\bRRSAgent\b" "\brudybot\b" "\bwhereisbot\b"
                  "\bZakim\b"
                  ;; #emacs
                  "\bams\b" "\bimnowme\b" "\bjordanb\b"
                  "\bkamo9088\b" "\bmicka\b" "\btknudsen\b"
                  "\bxah\b")
      erc-fool-highlight-type 'all
      erc-keywords '("ljupdate"))

.ercrc.el〉=
(require 'erc-fill)
(erc-fill-mode 1)
(setq erc-fill-column 72)
;; protected, for using ERC in emacs -q
(when (fboundp 'tess-hide-trailing-whitespace)
  (add-hook 'erc-mode-hook 'tess-hide-trailing-whitespace))

.ercrc.el〉=
(require 'erc-stamp)
(erc-stamp-mode 1)
(setq erc-insert-timestamp-function      'erc-insert-timestamp-left
      erc-timestamp-format               "[%H:%M] "
      erc-insert-away-timestamp-function 'erc-insert-timestamp-left
      erc-away-timestamp-format          "<%H:%M> ")

.ercrc.el〉=
(require 'erc-button)
(erc-button-mode 1)
(setq erc-button-wrap-long-urls  nil
      erc-button-buttonize-nicks nil)

.ercrc.el〉=
(require 'erc-netsplit)
(erc-netsplit-mode 1)

.ercrc.el〉=
(require 'erc-ring)
(erc-ring-mode 1)

.ercrc.el〉=
(require 'erc-dcc)

.ercrc.el〉=
(require 'erc-page)
(erc-page-mode 1)

.ercrc.el〉=
(require 'erc-track)
(erc-track-mode 1)
(setq erc-track-switch-direction 'importance)
(setq erc-track-exclude-types
      '("324" "329" "332" "333" "353"
        "JOIN" "NAMES" "NICK" "QUIT" "PART" "TOPIC"))
(global-set-key (kbd "C-c b") 'erc-track-switch-buffer)

.ercrc.el〉=
(defvar tess-modified-channels-length 0
  "Last recorded length of erc-modified-channels-alist'. This is updated each time tess-erc-growl' gets called from
`etc-track-list-changed-hook'.")

(defun tess-erc-growl () "Use growl for ERC track change notifications." (let ((modified-channels-length (length erc-modified-channels-alist))) (when (> modified-channels-length tess-modified-channels-length) (let ((msg (format "New messages in: %s" (mapconcat (lambda (pair) (buffer-name (car pair))) erc-modified-channels-alist ", ")))) (growl "IRC Activity" msg) (message "%s" msg))) (setq tess-modified-channels-length modified-channels-length)))

(when (and (eq system-type 'darwin) (locate-library "growl") window-system) (autoload 'growl "growl") (add-hook 'erc-track-list-changed-hook 'tess-erc-growl))

.ercrc.el〉=
;; emacs-w3m clobbers erc-track-mode's C-c C-SPC binding.
(eval-after-load "w3m"
  '(define-key w3m-mode-map (kbd "C-c C-SPC") 'erc-track-switch-buffer))

.ercrc.el〉=
(require 'erc-truncate)
(erc-truncate-mode 1)

.ercrc.el〉=
(defun erc-cmd-SHOW (&rest form)
  "Eval FORM and send the result and the original form as:

FORM => (eval FORM)." (let* ((form-string (mapconcat 'identity form " ")) (result (condition-case err (eval (read-from-whole-string form-string)) (error (format "Error: %s" error))))) (erc-send-message (format "%s => %S" form-string result)))) (add-to-list 'erc-noncommands-list 'erc-cmd-SHOW)

.ercrc.el〉=
(defun erc-cmd-OPME ()
  "Ask ChanServ to grant me op in this channel."
  (erc-message "PRIVMSG"
               (format "ChanServ op %s"
                       (erc-default-target)
                       (erc-current-nick))
               nil))

(defun erc-cmd-DEOPME () "Deop myself from this channel." (erc-cmd-DEOP (format "%s" (erc-current-nick))))

(defun erc-cmd-BAN (nick) "Ban NICK from this channel." (erc-server-send (format "mode %s +b !~%s@*" (erc-default-target) nick)))

.ercrc.el〉=
(defun erc-cmd-NP ()
  "Display currently playing iTunes track"
  (erc-send-message (shell-command-to-string "osascript -e 'tell
  application "iTunes" to if player state is playing then "NP: "
  & name of current track & " - " & artist of current track'")))
(add-to-list 'erc-noncommands-list 'erc-cmd-NP)

.ercrc.el〉=
(defun erc-cmd-YOW ()
  (erc-send-message (erc-replace-regexp-in-string "\n" "" (yow))))
(add-to-list 'erc-noncommands-list 'erc-cmd-YOW)

.ercrc.el〉=
(when (and (boundp 'viper-mode) viper-mode)
  (require 'erc-viper nil t))

.ercrc.el〉=
(defvar tess-erc-pcomplete-nick-postfix-overrides
  '(("Zakim" . ", "))
  "An alist of nicks which take non-default completion postfixes.
Each cell is of the form (NICK . POSTFIX), both strings.")

(defun tess-erc-pcomplete-format-nick (nick &optional postfix) "Return NICK, formatted for completion. Will use POSTFIX for formatting, unless an override is provided for NICK in tess-erc-pcomplete-nick-postfix-overrides'. If POSTFIX is not provided, we default to erc-pcomplete-nick-postfix'." (concat nick (or (cdr (assoc nick tess-erc-pcomplete-nick-postfix-overrides)) postfix erc-pcomplete-nick-postfix)))

(defun tess-pcomplete-erc-nicks (&optional postfix ignore-self) "Returns a list of nicks in the current channel. Optional argument POSTFIX is something to append to the nickname. If optional argument IGNORE-SELF is non-nil, don't return the current nick." (let ((users (if erc-pcomplete-order-nickname-completions (erc-sort-channel-users-by-activity (erc-get-channel-user-list)) (erc-get-channel-user-list))) (nicks nil)) (dolist (user users) (let ((nick (erc-server-user-nickname (car user)))) (unless (and ignore-self (string= nick (erc-current-nick))) (setq nicks (cons (tess-erc-pcomplete-format-nick nick postfix) nicks))))) (nreverse nicks)))

(eval-after-load "erc-pcomplete" '(defalias 'pcomplete-erc-nicks 'tess-pcomplete-erc-nicks))

.ercrc.el〉=
(defun tess-unprollify ()
  (goto-char (point-min))
  (while (search-forward "prolly" nil t)
    (replace-match "probably" nil t)))
(add-hook 'erc-insert-modify-hook 'tess-unprollify)

.ercrc.el〉=
Emoji in ERC

.ercrc.el〉=
;;; .ercrc.el ends here

rcirc

rcirc〉=
(setq rcirc-nick "hober")
(add-hook 'rcirc-mode-hook 'tess-hide-trailing-whitespace)
rcirc faces〉=
'(rcirc-my-nick ((t (:foreground "〈light cyan〉"))))
'(rcirc-mode-line-nick ((t (:foreground "〈medium magenta〉" :bold t))))
'(rcirc-other-nick ((t (:foreground "〈medium cyan〉"))))
'(rcirc-nick-in-message ((t (:foreground "〈light magenta〉" :bold t))))
'(rcirc-server ((t (:foreground "〈dark cyan〉"))))
'(rcirc-prompt ((t (〈prompt face〉))))

Utilities

SSH

Use SSH for M-x rsh, and make M-x ssh〉=
(when (fboundp 'rsh)
  (setq remote-shell-program "ssh")
  (defalias 'ssh 'rsh))

TRAMP

TRAMP: Transparent Remote Access over Multiple Protocols〉=
(when (locate-library "tramp")
  (setq tramp-default-method "sudo"))
#### Public keys
.ssh/public-keys〉=
niamh-pubkey-1〉〈niamh-pubkey-2〉〈niamh-pubkey-3〉 〈niamh-pubkey-4〉
〈oban-key-1〉〈oban-key-2〉〈oban-key-3〉〈oban-key-4〉〈oban-key-5〉〈oban-key-6〉〈oban-key-7〉〈oban-key-8〉
〈yt-key-1〉〈yt-key-2〉〈yt-key-3〉〈yt-key-4〉〈yt-key-5〉〈yt-key-6〉
〈ap-key-1〉〈ap-key-2〉〈ap-key-3〉〈ap-key-4〉〈ap-key-5〉〈ap-key-6〉
〈mb81-key-1〉〈mb81-key-2〉〈mb81-key-3〉〈mb81-key-4〉〈mb81-key-5〉〈mb81-key-6〉
〈mb101-key-1〉〈mb101-key-2〉〈mb101-key-3〉〈mb101-key-4〉〈mb101-key-5〉〈mb101-key-6〉
〈talisker-key-1〉〈talisker-key-2〉〈talisker-key-3〉〈talisker-key-4〉〈talisker-key-5〉〈talisker-key-6〉
〈metis-key-1〉〈metis-key-2〉〈metis-key-3〉〈metis-key-4〉〈metis-key-5〉〈metis-key-6

talisker-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDITed8UwhOFo8t1x5qyth2lvYr2Qu25s
talisker-key-2〉=
d0rPCpnDHCOZhPbEdYNXvNte1OUC1gMjBqrJDy5rYMY1jqKIA/Er7uy2w656E2vvouTCjk
talisker-key-3〉=
CDezdxAhVTG7ThEQOhQ54TUKbZ/PX03vGojxrYksC5opODcjAOtANbWqbk/QefmuaPqQpC
talisker-key-4〉=
feaES2pA/cACIGVcCuVWO0Bo2MM8Q2xlalEwUmrvkKbT3QVYd09+2PFZmK7rOxUT/+3DI7
talisker-key-5〉=
CWo1eIbGPZXHO4sFh+EeUQS7Wg28XALBdkq69RU04tck5PAJjcwfl6r9OctY57YIxhae9A
talisker-key-6〉=
ZaBHD1hhiwMXo4C7Rd3hEtBpTbjSRL tess@talisker.lan
oban-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5Z9rqoHoy3G9Rcdi972VzUE0Sh8RgY6
oban-key-2〉=
ITepfm9gyNbPdh3DNolA8eu4xE51J4nwDgObYLHyFIu6SA8moxJD71ggVVANIgHvQrLegE
oban-key-3〉=
ssrUFy8CDjQJBVCCHt4CeDnINOIeBz2jC8tuLC00LLWdo+XG5B7CsKW/3s1Tughh6K3Rj/
oban-key-4〉=
NupQOcDLjTOm6fuftc5/PeCZJeyB8ALuddH60rQ/Dknd5nhfL8pYhg1xTdjtLqQcDNu2fB
oban-key-5〉=
hC/aBR4jNLKCQoX6JU+bb+EsiPO07omz3QqIhrhnwDmKigOy60UebcblgDxwij/KA6b0JS
oban-key-6〉=
9OHwp744dN5aWKoiQ/GNBnjlfJuyxY+ReTnClkZAFQxBOsxnH2r4JoPUI7opLBgf22EnUD
oban-key-7〉=
RzcEBYeIqUOsprb47j88k7ym1iYRKolS7S70XknkYtDi5Kjo9q7T96AkZ3lRNumqsgjJ5G
oban-key-8〉=
sBnG4kAmvifxEIxsm3UjCeuTwGhiWTT5Fpb64BIUCC/fkLF8L7GJJAcohxN4c= ted@oban.lan
yt-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqZTGd0CMA6rh/W0ZLVPdLC4HKsfGsbWldU
yt-key-2〉=
ZuoyfG3/p7fE/gTeAMVCcKyCxQJ5HWDURKjyIsHFTbqNzyp0rWgbYWUa8nuMxJDulVSMtV
yt-key-3〉=
p2MBnzY94bU9qABHs/H4ZdagTLB0rkdZtgicukHbRq9SRKsTUmIaGRXNXUTCwEzdNSiKIY
yt-key-4〉=
sYXgdCzFvND16HcJmu3lqaNUWntQtRFcBvD85iCQ0pR/rEZ2Qi0w8BIvZ0uOMDU0NhFJ5R
yt-key-5〉=
r0xM8TqPQtpPYIIEwhjoew/eM2F30n46lTCd8UPmmjW1U+pG2O89tt1DKkioAPNxJGsCWZ
yt-key-6〉=
Q1DCDEyI5/PQ+Xlvsc+0T5/HkdMQ== ted@yt
niamh-pubkey-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAsHo/tCFtrZJWysF+RoRLlz5KmyKddhlIXG
niamh-pubkey-2〉=
09uQ/ige3Eph/MHflrPOxml5zsfwl/XVRzfSjBsPHCVTGEycB5/9V9eUT56wOrKRy+QZde
niamh-pubkey-3〉=
Iwr6WdPF7gzqibiR4s9sYcmppwwnNGEu1083Q/YRQR+hm3olYMlpuE/1XO+mhPE2n1k=
niamh-pubkey-4〉=
ted@niamh.cfhp.org
ap-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdyV7OLxxi1HeVmkqu32ggtOJVTXne0n
ap-key-2〉=
PmGmtyzGZRvZh7OSNw/471KUneQK4hDl8rVLUGBsOJN75R0c9bnmUCCONBkkNBLGwIkB5C
ap-key-3〉=
fywxY/8vbXqAycVQJIc2scbrGMm1KIiICytcou+P10s85HPGoGd66seB8HeUNr9ovfhG+5
ap-key-4〉=
s+BY3B08al8K23IdEIQ8Bt7qz9RgoLuoM+65RNgmf1phut9kWyLcXto5hKFjTU0SoFcFMR
ap-key-5〉=
yrKtZUJHhcPwnY+DLrAh3G47tbbObQ82Un6gq4kBJzDBenqfvGm3QW7Gy43SqNlf0ETKJe
ap-key-6〉=
m/SkzCeW2rToIyTbYFN9L6ODqzITiX eoconnor@apple
mb81-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCpb0tkzPGNQndtUmJaslLpsq25sU1YFP
mb81-key-2〉=
RNytlnAdQqT9kqHNcn6rxRi81ZJsY7MsDvgcknyVnVQCZOWiKT74Cjet2ZKpZ4Evci2WYl
mb81-key-3〉=
bge++sxImBP7swAYEt1yoUmFsEAGivp2ymxRFgiKDTpAD+PGZW4WeOhYrITIkxNnTnXMiW
mb81-key-4〉=
IHcfkh6WyS2ftltKVPJViwdLn2NHnVs9tIWpMJclGMx9LK9UgPJIcBjhPoNd4if3Stg0Ev
mb81-key-5〉=
8ZOOk+VgTNj+QNVLtkF4EQ6a5C+YC07DX+Qx/Otn7k1vYL6s64Mlw/26pPMFNez2zFghp+
mb81-key-6〉=
hLApIY/e3QGq3Xv4stZXqy0hoalNk1 toconnor@toconnor-mb.local
mb101-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiW5rYMB7caLPLiU3izNcKPYbxbn62SU
mb101-key-2〉=
xjJjfQc6QgaZtB9As9rdglwHvuu6II1IQS4EQgw1cDGnnm04LUI9YcO+DgfzBJqUiYrhQQ
mb101-key-3〉=
QS71tS2Bt0LzLAZ0scpIu4UKexo6/5R23g90nxnCjJLX2h9ADdqJZf8RbJFhgNuAB1wj86
mb101-key-4〉=
Z0kJAZftLrY3ETUo+uubu8P4ZYPoIZzkulugwiOKYYaIQ6vB3BZ0t776hSIvEwjNMl3fpu
mb101-key-5〉=
vYS+K4lzqqC6MATceS4FA7KECGtjpTspHDTH/7DoLD3phWMOdgYPrbIwyBKvmqh2pTTao0
mb101-key-6〉=
8wlHhQtLcw+WQQOMBh8Voxs20rJMSR eoconnor@Theresas-MacBook.local
metis-key-1〉=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCTu8CaPpwOug/xY0pVQwCbHlEMORxTFs
metis-key-2〉=
t/mhIy7b4kVF16VJFhFqE+EyCBIUdq9ud2YYGVH+E0d78E37yJAzsubF0zNCRbTtMPrJg+
metis-key-3〉=
uAzDcdh1H6uuZF0VyUZjy9I11sfBHc7NLW9BceAXg+t3rJEQCvUdF8fAK1Zm4pzGdyVSUD
metis-key-4〉=
hNtu6mQ7D6HPxX2QLSz3PCDaVzRxmCt7KMWiEIVcOSCuXrrv75xA3lW9o5zfPeGfMXxHXG
metis-key-5〉=
tM3Ci+EVxg3PlaC2FG6ECMHwqrKy3A+Pa0tVivD8K471WzN2idYuI9KyL7DGaW5lIWVXCP
metis-key-6〉=
Djdip9ex4DJmrMKrCTi4eNsLrrSoBP tess@Metis
.ssh/config〉=
ControlMaster auto

.ssh/config〉=
ForwardAgent yes
ForwardX11 no

.ssh/config〉=
# My machines

Host mallow HostName mallow.cfhp.org User tess ForwardX11 yes

.ssh/config〉=
# Default settings.

Host *

MACs hmac-sha1,hmac-md5,hmac-ripemd160,hmac-sha1-96,hmac-md5-96

ForwardAgent no

Info, man, apropos, and other help

info title face〉=
:foreground "〈light red〉"
info xref face〉=
:foreground "〈medium cyan〉"
info faces〉=
'(Info-title-1-face ((t (〈info title face〉))))
'(Info-title-2-face ((t (〈info title face〉))))
'(Info-title-3-face ((t (〈info title face〉))))
'(Info-title-4-face ((t (〈info title face〉))))
'(info-header-node ((t (〈info title face〉))))
'(info-header-xref ((t (〈info xref face〉))))
'(info-menu-5 ((t ())))
'(info-menu-star ((t ())))
'(info-menu-header ((t (〈info title face〉))))
'(info-node ((t (〈info title face〉))))
'(info-title-1 ((t (〈info title face〉))))
'(info-title-2 ((t (〈info title face〉))))
'(info-title-3 ((t (〈info title face〉))))
'(info-title-4 ((t (〈info title face〉))))
'(info-xref ((t (〈info xref face〉))))

man face variables〉=
'(Man-overstrike-face 'font-lock-variable-name-face)
'(Man-underline-face 'font-lock-string-face)

configure woman〉=
(setq woman-use-own-frame nil)

woman faces〉=
'(woman-italic-face ((t (:slant italic))))
'(woman-bold-face ((t (:bold t))))
'(woman-unknwon-face ((t (:foreground "〈medium cyan〉"))))
'(woman-addition-face ((t (:foreground "〈medium green〉"))))

apropos face variables〉=
'(apropos-symbol-face 'font-lock-keyword-face)
'(apropos-keybinding-face 'font-lock-constant-face)
'(apropos-label-face 'font-lock-type-face)
'(apropos-property-face 'font-lock-string-face)
'(apropos-match-face 'font-lock-function-name-face)

hyper apropos faces〉=
'(hyper-apropos-documentation ((t (:foreground "〈light white〉"))))
'(hyper-apropos-hyperlink ((t (〈link face〉))))
'(hyper-apropos-major-heading ((t (:foreground "〈light yellow〉"))))
'(hyper-apropos-section-heading ((t (:foreground "〈medium yellow〉"))))
'(hyper-apropos-apropos-heading ((t (:foreground "〈dark yellow〉"))))
'(hyper-apropos-apropos-warning ((t (〈warning face〉))))

cfengine

cfengine〉=
(when (locate-library "cfengine")
  (autoload 'cfengine-mode "cfengine" nil t)
  (add-to-list 'auto-mode-alist
               '("cf\\(\\.\\|agent\\.conf\\)" . cfengine-mode))
  (defalias 'cfengine-beginning-of-line 'beginning-of-line)
  (setq cfengine-indent 4))

Ledger

ledger-mode〉=
(when (locate-library "ledger")
  (autoload 'ledger-mode "ledger" nil t))

Operating Systems

Note to self: The following snippet (Configure ls colors) gets included in both .bashrc and .zshrc, so it needs to remain polyglot bash / zsh.

Configure ls colors〉=
if ls --version > /dev/null 2>&1; then # ls is from GNU coreutils
    〈ls in linux〉
else
    〈ls in freebsd〉
fi
OS-specific tweaks〉=
macOS shell aliases

if [[ $OSTYPE = 'Darwin' ]]; then 〈fix top under macOS〉 fi

Setting PATH in Zsh〉=
if command-recognized xcode-select; then
    add-to-path xcode-select -p/usr/bin xcode-select -p/usr/local/bin
    add-to-path xcode-select -p/Library/Frameworks/Python3.framework/Versions/Current/bin
fi

Setting PATH in PowerShell〉=
if (Get-Command xcode-select 2> $null) {
    Join-Paths (xcode-select -p) usr bin | Add-PathsToEnvPATH
}

Add Visual Studio tools to PATH〉=
# Make Visual Studio-provided command line utilities work in this

instance of PowerShell.

$devshell_loaded = Get-Module Microsoft.VisualStudio.DevShell

if ($devshell_loaded.count -eq 0) { if (${Env:ProgramFiles(x86)}) { $vswhere = Join-Paths ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio' 'Installer' 'vswhere.exe'

    if (Test-Path $vswhere) {
        $vsroot = &$vswhere -Property installationpath
        $devshell = Join-Paths ${vsroot} 'Common7' 'Tools' 'Microsoft.VisualStudio.DevShell.dll'

        if (Test-Path $devshell) {
            Import-Module $devshell
        }
    }
}

}

$devshell_loaded = Get-Module Microsoft.VisualStudio.DevShell

if ($devshell_loaded.count -gt 0) { Enter-VsDevShell -VsInstallPath $vsroot | Out-Null }

Remove-Variable 'devshell_loaded'

FreeBSD

FreeBSD keymap〉=
if [[ $TERM = 'cons25' ]]; then
    kbdcontrol -l ~/.freebsd-keymap
    export HOBER_KEYMAP='YES'
fi

Handle my FreeBSD keymap (Emacs)〉=
(let ((hober-keymap (getenv "HOBER_KEYMAP"))
      (term (getenv "TERM")))
  (when (and hober-keymap (string-equal hober-keymap "YES")
             term (string-equal term "cons25"))
    〈FreeBSD console〉))

FreeBSD console〉=
(when (fboundp 'normal-erase-is-backspace-mode)
  (normal-erase-is-backspace-mode -1))
FreeBSD console〉=
(define-key function-key-map (kbd "ESC [ }") (kbd ""))
FreeBSD console〉=
(define-key function-key-map (kbd "ESC [ J") 'event-apply-super-modifier)
FreeBSD console〉=
(define-key function-key-map (kbd "ESC [ ~") 'event-apply-hyper-modifier)

Console keymap

.freebsd-keymap〉=
#                                                         alt
# scan                       cntrl          alt    alt   cntrl lock
# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state
# ------------------------------------------------------------------
  000   nop    nop    nop    nop    nop    nop    nop    nop     O
  001   esc    esc    esc    esc    esc    esc    esc    esc     O
  002   '1'    '!'    nop    nop    177    161    nop    nop     O
  003   '2'    '@'    nul    nul    178    192    128    128     O
  004   '3'    '#'    nop    nop    179    163    nop    nop     O
  005   '4'    '$'    nop    nop    180    164    nop    nop     O
  006   '5'    '%'    nop    nop    181    165    nop    nop     O
  007   '6'    '^'    rs     rs     182    222    158    158     O
  008   '7'    '&'    nop    nop    183    166    nop    nop     O
  009   '8'    '*'    nop    nop    184    170    nop    nop     O
  010   '9'    '('    nop    nop    185    168    nop    nop     O
  011   '0'    ')'    nop    nop    176    169    nop    nop     O
  012   '-'    '_'    us     us     173    223    159    159     O
  013   '='    '+'    nop    nop    189    171    nop    nop     O
  014   del    del    bs     bs     255    255    136    136     O
  015   ht     ht     ht     ht     137    137    137    137     O
  016   'q'    'Q'    dc1    dc1    241    209    145    145     C
  017   'w'    'W'    etb    etb    247    215    151    151     C
  018   'e'    'E'    enq    enq    229    197    133    133     C
  019   'r'    'R'    dc2    dc2    242    210    146    146     C
  020   't'    'T'    dc4    dc4    244    212    148    148     C
  021   'y'    'Y'    em     em     249    217    153    153     C
  022   'u'    'U'    nak    nak    245    213    149    149     C
  023   'i'    'I'    ht     ht     233    201    137    137     C
  024   'o'    'O'    si     si     239    207    143    143     C
  025   'p'    'P'    dle    dle    240    208    144    144     C
  026   '['    '{'    esc    esc    219    251    155    155     O
  027   ']'    '}'    gs     gs     221    253    157    157     O
  028   cr     cr     nl     nl     141    141    138    138     O
  029   lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl   O
  030   'a'    'A'    soh    soh    225    193    129    129     C
  031   's'    'S'    dc3    dc3    243    211    147    147     C
  032   'd'    'D'    eot    eot    228    196    132    132     C
  033   'f'    'F'    ack    ack    230    198    134    134     C
  034   'g'    'G'    bel    bel    231    199    135    135     C
  035   'h'    'H'    bs     bs     232    200    136    136     C
  036   'j'    'J'    nl     nl     234    202    138    138     C
  037   'k'    'K'    vt     vt     235    203    139    139     C
  038   'l'    'L'    ff     ff     236    204    140    140     C
  039   ';'    ':'    nop    nop    187    186    nop    nop     O
  040   '''    '"'    nop    nop    167    162    nop    nop     O # "
  041   '`'    '~'    nop    nop    224    254    nop    nop     O
  042   lshift lshift lshift lshift lshift lshift lshift lshift  O
  043   '\'    '|'    fs     fs     220    252    156    156     O
  044   'z'    'Z'    sub    sub    250    218    154    154     C
  045   'x'    'X'    can    can    248    216    152    152     C
  046   'c'    'C'    etx    etx    227    195    131    131     C
  047   'v'    'V'    syn    syn    246    214    150    150     C
  048   'b'    'B'    stx    stx    226    194    130    130     C
  049   'n'    'N'    so     so     238    206    142    142     C
  050   'm'    'M'    cr     cr     237    205    141    141     C
  051   ','    '<'    nop    nop    172    188    nop    nop     O
  052   '.'    '>'    nop    nop    174    190    nop    nop     O
  053   '/'    '?'    nop    nop    175    191    nop    nop     O
  054   rshift rshift rshift rshift rshift rshift rshift rshift  O
  055   '*'    '*'    nl     nl     170    170    138    138     O
  056   lalt   lalt   lalt   lalt   lalt   lalt   lalt   lalt    O
  057   ' '    ' '    nul    nul    160    160    128    128     O
  058   lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl   O
  059   fkey01 fkey13 fkey25 fkey37 scr01  scr11  scr01  scr11   O
  060   fkey02 fkey14 fkey26 fkey38 scr02  scr12  scr02  scr12   O
  061   fkey03 fkey15 fkey27 fkey39 scr03  scr13  scr03  scr13   O
  062   fkey04 fkey16 fkey28 fkey40 scr04  scr14  scr04  scr14   O
  063   fkey05 fkey17 fkey29 fkey41 scr05  scr15  scr05  scr15   O
  064   fkey06 fkey18 fkey30 fkey42 scr06  scr16  scr06  scr16   O
  065   fkey07 fkey19 fkey31 fkey43 scr07  scr07  scr07  scr07   O
  066   fkey08 fkey20 fkey32 fkey44 scr08  scr08  scr08  scr08   O
  067   fkey09 fkey21 fkey33 fkey45 scr09  scr09  scr09  scr09   O
  068   fkey10 fkey22 fkey34 fkey46 scr10  scr10  scr10  scr10   O
  069   nlock  nlock  nlock  nlock  nlock  nlock  nlock  nlock   O
  070   slock  slock  slock  slock  slock  slock  slock  slock   O
  071   fkey49 '7'    '7'    '7'    183    183    183    183     N
  072   fkey50 '8'    '8'    '8'    184    184    184    184     N
  073   fkey51 '9'    '9'    '9'    185    185    185    185     N
  074   fkey52 '-'    '-'    '-'    173    173    173    173     N
  075   fkey53 '4'    '4'    '4'    180    180    180    180     N
  076   fkey54 '5'    '5'    '5'    181    181    181    181     N
  077   fkey55 '6'    '6'    '6'    182    182    182    182     N
  078   fkey56 '+'    '+'    '+'    171    171    171    171     N
  079   fkey57 '1'    '1'    '1'    177    177    177    177     N
  080   fkey58 '2'    '2'    '2'    178    178    178    178     N
  081   fkey59 '3'    '3'    '3'    179    179    179    179     N
  082   fkey60 '0'    '0'    '0'    176    176    176    176     N
  083   del    '.'    '.'    '.'    174    174    boot   boot    N
  084   us     us     us     us     us     us     us     us      O
  085   nop    nop    nop    nop    nop    nop    nop    nop     O
  086   nop    nop    nop    nop    nop    nop    nop    nop     O
  087   fkey11 fkey23 fkey35 fkey47 scr11  scr11  scr11  scr11   O
  088   fkey12 fkey24 fkey36 fkey48 scr12  scr12  scr12  scr12   O
  089   nop    cr     cr     cr     141    141    141    141     N
  090   rctrl  rctrl  rctrl  rctrl  rctrl  rctrl  rctrl  rctrl   O
  091   nop    '/'    '/'    '/'    175    175    175    175     N
  092   nscr   pscr   debug  debug  nop    nop    nop    nop     O
  093   ralt   ralt   ralt   ralt   ralt   ralt   ralt   ralt    O
  094   fkey49 fkey49 fkey49 fkey49 fkey49 fkey49 fkey49 fkey49  O
  095   fkey50 fkey50 fkey50 fkey50 fkey50 fkey50 fkey50 fkey50  O
  096   fkey51 fkey51 fkey51 fkey51 fkey51 fkey51 fkey51 fkey51  O
  097   fkey53 fkey53 fkey53 fkey53 fkey53 fkey53 fkey53 fkey53  O
  098   fkey55 fkey55 fkey55 fkey55 fkey55 fkey55 fkey55 fkey55  O
  099   fkey57 fkey57 fkey57 fkey57 fkey57 fkey57 fkey57 fkey57  O
  100   fkey58 fkey58 fkey58 fkey58 fkey58 fkey58 fkey58 fkey58  O
  101   fkey59 fkey59 fkey59 fkey59 fkey59 fkey59 fkey59 fkey59  O
  102   fkey60 paste  fkey60 fkey60 fkey60 fkey60 fkey60 fkey60  O
  103   fkey61 fkey61 fkey61 fkey61 fkey61 fkey61 boot   fkey61  O
  104   slock  saver  slock  saver  susp   nop    susp   nop     O
  105   fkey62 fkey62 fkey62 fkey62 fkey62 fkey62 fkey62 fkey62  O
  106   fkey63 fkey63 fkey63 fkey63 fkey63 fkey63 fkey63 fkey63  O
  107   fkey64 fkey64 fkey64 fkey64 fkey64 fkey64 fkey64 fkey64  O
  108   nop    nop    nop    nop    nop    nop    nop    nop     O

Linux

RPM specs

rpm-spec-mode.el fetch rule〉=
rpm-spec-mode.el:
        curl -O http://www.tihlde.org/~stigb/rpm-spec-mode.el
Open RPM spec files in rpm-spec-mode〉=
(when (locate-library "rpm-spec-mode")
  〈defun user-mail-address〉
  (autoload 'rpm-spec-mode "rpm-spec-mode" nil t)
  ;; RPM specfiles are .spec
  (add-to-list 'auto-mode-alist '("\\.spec\\'" . rpm-spec-mode)))

macOS

Define utilities for locating and running Mac apps〉=
(defun tess-run-mac-app (app)
  "Runs `app'."
  (interactive "sApp: ")
  (call-process "open" nil nil nil "-a" app))
(defalias 'oa 'tess-run-mac-app)

(defun tess-locate-mac-app (app) "Returns the on-disk location of app', or nil if it can't be found. Requires oa' to be installed." (and (executable-find "oa") (with-temp-buffer (let ((exit-code (call-process "oa" nil t nil "-d" app))) (if (= exit-code 0) (buffer-substring (point-min) (1- (point-max))) nil)))))

Ensure XCode Command Line Tools are in exec-path〉=
(when (executable-find "xcode-select")
  (let ((xcode-developer-path
         (substring (shell-command-to-string "xcode-select -p") 0 -1)))
    (add-to-list 'exec-path
                 (expand-file-name "usr/bin" xcode-developer-path))))

Stop Cocoa Emacs from using the system highlight〉=
(setq ns-use-system-highlight-color nil)

fix top under macOS〉=
alias top='top -ocpu -Otime'
Fix Emacs behavior when in the macOS dock〉=
(when (and (eq system-type 'darwin)
           (boundp 'mac-apple-event-map)
           (keymapp mac-apple-event-map))
  (define-key mac-apple-event-map
    [core-event reopen-application] 'raise-frame))

Games

Steam

game launchers〉=
$SteamCommon = Join-Paths ${Env:ProgramFiles(x86)} 'Steam' 'steamapps' 'common'

function Start-SteamGame { [CmdletBinding(PositionalBinding=$false)] param( [Parameter(Mandatory=$true,Position=0)] [ValidateScript({ Join-Paths $SteamCommon $_ | Test-Path -PathType Container })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $glob = $wordToComplete + '*' (Join-Paths $SteamCommon $glob | Get-ChildItem).Name })] [string]$Game, [string]$Executable=$Game )

if ($Game -eq 'Cities_Skylines') {
    $Executable = 'Cities'
}

$GameDir = Join-Paths $SteamCommon $Game
$GameExec = Join-Paths $GameDir "${Executable}.exe"
if (Test-Path $GameExec -PathType Leaf) {
    Start-Process $GameExec -WorkingDirectory $GameDir
} else {
    Write-Error "Unable to locate .exe file for ${Game}!"
}

} Set-Alias -Name play -Value Start-SteamGame

function Start-CitiesSkylines { Start-SteamGame -Game Cities_Skylines -Executable Cities } Set-Alias -Name cities -Value Start-CitiesSkylines

Star Trek Online

game launchers〉=
function Repair-StarTrekOnline {
    $sto = Join-Paths ${Env:ProgramFiles(x86)} 'Star Trek Online_en' 'Star Trek Online'

Write-Host 'Removing patch and prepatch files...'

Join-Paths $sto 'Live' '.patch' | Get-ChildItem | Remove-Item -Force
Join-Paths $sto 'Live' 'prepatch' 'piggs' | Get-ChildItem | Remove-Item -Force

} Set-Alias -Name fix-sto -Value Repair-StarTrekOnline

function Start-Arc { $arcdir = Join-Paths ${Env:ProgramFiles(x86)} Arc $arcexe = Join-Paths $arcdir ArcLauncher.exe Write-Host 'Launching Arc...' Start-Process -FilePath $arcexe -WorkingDirectory $arcdir } Set-Alias -Name arc -Value Start-Arc

function Start-StarTrekOnline { $stodir = Join-Paths ${Env:ProgramFiles(x86)} 'Star Trek Online_en' $stoexe = Join-Paths $stodir 'Star Trek Online.exe' Write-Host 'Launching Star Trek Online...' Start-Process -FilePath $stoexe -WorkingDirectory $stodir } Set-Alias -Name sto -Value Start-StarTrekOnline

Fortune

Pants〉=
Something just occurred to me.
My pants were built by the lowest bidder.

    — Imler, in rhit.gas.stations.bigfoot

In college and for a few years after I maintained a pretty large fortune file. I gave up on that effort a long time ago, but recently I started making zsh print out fortunes at login, so I started over. The actual quotes are dispersed throughout this document. Here's where we pull them all together:

fortune〉=
Share and Enjoy!〉
%
〈Soft Animal〉
%
〈The Allure of Love〉
%
〈Mercy, Moderation, and Modesty〉
%
〈What are they to me?〉
%
〈Intricate Brocade〉
%
〈Pants〉
%
〈Machine Translation〉
%
〈Raised by wolves

I run fortune at login time.

Run fortune at login〉=
Regenerate ~/fortune.dat if we need to

command-recognized fortune || autoload fortune

print fortune ~/fortune | $CAT

Run fortune at login (PowerShell)〉=
if ($IsLoginShell) {
    fortune
}

Some versions of fortune use a binary file to index into the text file containing all the fortunes. This is how I ensure that binary file is up-to-date at login time.

Regenerate ~/fortune.dat if we need to〉=
if command-recognized strfile; then
    if [[ ! -r ~/fortune.dat || ~/fortune -nt ~/fortune.dat ]]; then
        strfile ~/fortune > /dev/null
    fi
fi

macOS doesn't ship with fortune by default so, instead of installing it, I wrote a drop-in replacement as a zsh function. Why, you might be asking. I honestly don't know. It seemed like a good idea at the time.

.local/share/zsh/functions/fortune〉=
#!/usr/bin/env zsh

emulate -LR zsh

SCRIPT_NAME=${0:t}

typeset -a DEBUG

debug() { emulate -L zsh if (( ${#DEBUG} > $0 )); then shift 1 print "DEBUG: ${*}" >&2 fi }

help() { emulate -L zsh print "USAGE: $SCRIPT_NAME [-aDfhow] [file*|all]" return 0 }

fortune() { emulate -LR zsh

# Parse command line arguments.

typeset -a FLAGS
zmodload zsh/zutil
zparseopts -a FLAGS -D -E -F - a D+=DEBUG f h -help o w || return 1

debug 1 "parsed flags are (-D $FLAGS)"
debug 1 "other arguments are ($*)"

# Print help and exit if -h or --help were passed.

if (( ${FLAGS[(ie)-h]} <= $#FLAGS )); then
    help
    return $?
elif (( ${FLAGS[(ie)--help]} <= $#FLAGS )); then
    help
    return $?
fi

# Find the fortune files to use.

typeset -a DEFAULT_SOURCES SOURCES UNFILTERED

if [[ -d /usr/share/games/fortune/ ]]; then
    DEFAULT_SOURCES=("${(@f)$(ls -1 /usr/share/games/fortune/)}")
else
    DEFAULT_SOURCES=(~/fortune ~/fortune-o)
fi

for ARG in $*; do
    if [[ $ARG == "all" ]]; then
        for DEFAULT in $DEFAULT_SOURCES; do
            if [[ -r $DEFAULT ]]; then
                UNFILTERED+=$DEFAULT
            fi
        done
        break
    elif [[ -r $ARG ]]; then
        UNFILTERED+=$ARG
    fi
done

if (( ${#UNFILTERED} == 0 )); then
    for DEFAULT in $DEFAULT_SOURCES; do
        if [[ -r $DEFAULT ]]; then
            UNFILTERED+=$DEFAULT
        fi
    done
fi

if (( ${FLAGS[(ie)-a]} <= $#FLAGS )); then
    set -A SOURCES ${(@)UNFILTERED}
elif (( ${FLAGS[(ie)-o]} <= $#FLAGS )); then
    SOURCES=()
    for SOURCE in ${(@)UNFILTERED}; do
        if [[ $SOURCE == *-o ]]; then
            SOURCES+=$SOURCE
        fi
    done
else
    SOURCES=()
    for SOURCE in $UNFILTERED; do
        if [[ $SOURCE != *-o ]]; then
            SOURCES+=$SOURCE
        fi
    done
fi

# Error out if we couldn't find any usable fortune files.

if (( $#SOURCES == 0 )); then
    print "ERROR: no usable fortune files found."
    return 1
fi

# If -f was specified, we're done! Just print the list of fortune
# files we would have used, and exit.

if (( ${FLAGS[(ie)-f]} <= $#FLAGS )); then
    for SOURCE in $SOURCES; do
        print $SOURCE
    done
    return 0
fi

debug 1 "will parse these fortune files: ($SOURCES)"

# Collect fortunes from each file.

typeset -a FORTUNES

for SOURCE in $SOURCES; do
    FORTUNE=''
    typeset -a FLINES=("${(@f)"$(<$SOURCE)"}")
    for FLINE in $FLINES; do
        if [[ $FLINE == '%' ]]; then
            FORTUNES+=$FORTUNE
            FORTUNE=''
        elif [[ $FORTUNE == '' ]]; then
            FORTUNE="${FLINE}"
        else
            FORTUNE="${FORTUNE}

${FLINE}" fi done if [[ $FORTUNE != '' ]]; then FORTUNES+=$FORTUNE fi done

# Choose a random fortune and print it.

FORTUNE=${FORTUNES:$[RANDOM%$#FORTUNES]:1}

print -r $FORTUNE

# Delay before returning, if the user asked us to.

if (( ${FLAGS[(ie)-w]} <= $#FLAGS )); then
    # Calculate delay based on length of the fortune. Coefficient of
    # 0.025 seconds per character based on empirical observation of
    # my own reading speed.
    (( DELAY = 0.025 * ${#FORTUNE} ))
    debug 1 "waiting for $DELAY seconds"
    sleep $DELAY
fi

return 0

}

fortune "$@"

I also implemented it in PowerShell. It's a bit shorter.

fortune (PowerShell)〉=
function Get-Fortune {
    param([string]$Path=(Join-Paths $Home 'fortune'))
    Get-Content $Path -Delimiter "`n%`n" | Get-Random
}
Set-Alias -Name fortune -Value Get-Fortune

Nethack

.nethackrc〉=
# Character
OPTIONS=name:Tess
OPTIONS=gender:female
OPTIONS=catname:Ash
OPTIONS=dogname:Maggie
OPTIONS=horsename:Ed
OPTIONS=fruit:durian

Startup

OPTIONS=!news,!splash_screen

UI

OPTIONS=color OPTIONS=use_darkgray OPTIONS=altmeta OPTIONS=hilite_pet OPTIONS=lit_corridor OPTIONS=hitpointbar OPTIONS=showexp,showscore,time

Reporting at endgame

OPTIONS=disclose:+i +a nv -c -g

Auto-pickup safe things

OPTIONS=autopickup OPTIONS=pickup_types:$?!/="+% OPTIONS=pickup_burden:unencumbered OPTIONS=pickup_thrown

Never pick these up

AUTOPICKUP_EXCEPTION="> corpse"

Nethack settings〉=
export NETHACKOPTIONS='name:Tess, align:neutral, race:Elf, role:Rogue,
gender:female, fruit:apple, horsename:Ed, dogname:Maggie, catname:Ash,
color'
enable screen's nethack mode〉=
nethack on
freeciv.serv〉=
# Server commands to set up a nice game.

FreeCiv

freeciv.serv〉=
# map
set size 4
set generator 3
set landmass 40

freeciv.serv〉=
# starting conditions
set startpos 3
set dispersion 4

freeciv.serv〉=
# cities
set citynames 3
set citymindist 4

freeciv.serv〉=
# ai
set aifill 8
easy

freeciv.serv〉=
# gameplay
set barbarians 0
set onsetbarbs 5000
set civilwarsize 6

freeciv.serv〉=
# endgame
set spacerace 0
set endyear 2100

Emacs Games〉=
(add-hook 'tetris-mode-hook 'tess-hide-trailing-whitespace)

Emacs Games〉=
(when (locate-library "chess-auto")
  (load-library "chess-auto"))

Emacs Games〉=
(when (locate-library "malyon")
  (autoload 'malyon "malyon" nil t)
  (add-hook 'malyon-mode-hook 'tess-hide-trailing-whitespace))

Documents

Editing documents

Wikis

oddmuse.el fetch rule〉=
oddmuse.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/oddmuse.el

EmacsWiki〉=
(when (require 'oddmuse nil t)
  (setq oddmuse-directory "~/wikis")
  (oddmuse-mode-initialize))

defun tess-w3m-edit-emacswiki-page〉=
(defun tess-w3m-edit-emacswiki-page (url)
  (let ((node (substring (substring w3m-current-url
                                    (string-match "wiki[/?][^/&=]+\'"
                                                  w3m-current-url))
                         5)))
    (w3m-goto-url (concat "http://www.emacswiki.org/cgi-bin/wiki"
                          "?action=edit;id=" node))))

editing emacswiki pages with w3m〉=
(add-to-list 'w3m-edit-function-alist
             '(".emacswiki.org/cgi-bin/wiki."
               . tess-w3m-edit-emacswiki-page))
wikiarea〉=
(when (locate-library "wikiarea")
  (autoload 'wikiarea "wikiarea" nil t)
  (setq wikiarea-managed-directory
        (expand-file-name "emacs-wiki/" tess-elisp-dir)))

wikipedia elisp fetch rules〉=
WIKIPEDIA_ROOT="http://cvs.gna.org/viewcvs/*checkout*/wikipedia-el"
WIKIPEDIA_PATH="wikipedia-el/wikipedia.el?rev=HEAD&content-type=text/plain"
wikipedia.el:
        curl -o wikipedia.el $(WIKIPEDIA_ROOT)/$(WIKIPEDIA_PATH)
wikipedia elisp fetch rules〉=
wikipedia-mode.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/wikipedia-mode.el
wikipedia major mode〉=
(when (locate-library "wikipedia-mode")
  (autoload 'wikipedia-mode "wikipedia-mode" nil t)
  (add-to-list 'auto-mode-alist '("\.wiki\'" . wikipedia-mode)))

mediawiki major mode〉=
(when (locate-library "mediawiki-mode")
  (autoload 'mediawiki-mode "mediawiki-mode" nil t)
  (add-to-list 'auto-mode-alist '("\.mw$" . mediawiki-mode)) ; $

;; do this in a hook because mediawiki-mode resets its keybindings on ;; evey mode change. (add-hook 'mediawiki-mode-hook (lambda () (define-key mediawiki-mode-map (kbd "C-x C-s") 'save-buffer))))

TeX

disable TeX {sub,super}script frobbing〉=
;; AUC-TeX
(setq font-latex-script-display nil)
;; TeX mode
(eval-after-load "tex-mode"
  '(defun tex-font-lock-suscript (pos)
     '(face default)))

AUCTeX〉=
(when (require 'tex-site nil t)
  (setq-default TeX-auto-untabify nil)
  (setq TeX-auto-untabify nil))

latex template〉=
(let ((latex-template "template.tex"))
  (when (file-exists-p (expand-file-name latex-template
                                         auto-insert-directory))
    (add-to-list 'auto-insert-alist
                 `(("\.tex\'" . "LaTeX") . ,latex-template))))

insert/template.tex〉=
\documentclass[10pt,letterpaper,oneside,openany]{article}

insert/template.tex〉=
\title{}
\author{Theresa O'Connor $<$\href{mailto:tess@oconnor.cx}{tess@oconnor.cx}$>$}
\date{\today}

insert/template.tex〉=
\usepackage[letterpaper,body={6.5in,9in},top=1in,left=1in]{geometry}

insert/template.tex〉=
\newif\ifPDF
\ifx\pdfoutput\undefined\PDFfalse
\else\ifnum\pdfoutput > 0\PDFtrue
     \else\PDFfalse
     \fi
\fi

insert/template.tex〉=
\ifPDF
  \usepackage[pdftex]{color,graphicx}
  \usepackage[pdftex,pdfpagemode=UseNone,colorlinks=true,
              urlcolor=blue,pdfstartview={FitH},
              plainpages=false]{hyperref}
\else
  \usepackage[dvips]{color,graphicx}
  \usepackage[hypertext]{hyperref}
\fi

insert/template.tex〉=
\usepackage{makeidx} \makeindex

insert/template.tex〉=
\usepackage{fancyhdr}
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0pt}
\lhead{} \chead{} \rhead{}
\lfoot{} \cfoot{\thepage} \rfoot{}

insert/template.tex〉=
\setlength{\parindent}{0pt}
\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}

insert/template.tex〉=
\begin{document}
\maketitle
\end{document}
font latex faces〉=
'(font-latex-bold-face ((t (:bold t :foreground "〈medium green〉"))));%
'(font-latex-italic-face ((t (:slant italic :foreground "〈medium green〉"))));%
'(font-latex-math-face ((t (〈math face〉))))
'(font-latex-sectioning-0-face ((t (:foreground "〈medium yellow〉"))))
'(font-latex-sectioning-1-face ((t (:foreground "〈medium yellow〉"))))
'(font-latex-sectioning-2-face ((t (:foreground "〈medium yellow〉"))))
'(font-latex-sectioning-3-face ((t (:foreground "〈medium yellow〉"))))
'(font-latex-sectioning-4-face ((t (:foreground "〈medium yellow〉"))))
`(font-latex-sedate-face ((t 〈dim this face when appropriate〉)))
'(font-latex-string-face ((t (〈string face〉))))
'(font-latex-subscript-face ((t ())))
'(font-latex-title-1-face ((t (:foreground "〈medium blue〉"))))
'(font-latex-title-2-face ((t (:foreground "〈medium blue〉"))));%
'(font-latex-title-3-face ((t (:foreground "〈medium blue〉"))))
'(font-latex-title-4-face ((t (:foreground "〈medium blue〉"))))
'(font-latex-verbatim-face ((t ())))
'(font-latex-warning-face ((t (〈warning face〉))))

HTML and XML

Web Development〉=
(defvar tess-xml-mode 'xml-mode
  "Which major-mode to use for editing XML.")

(defvar tess-html-mode 'html-mode "Which major-mode to use for editing HTML.")

(defun tess-url-encode-region (start end) "Encode the region from START to END as if it were a URL." (interactive "r") (let ((str (buffer-substring-no-properties start end))) (delete-region start end) (insert (url-encode-url str))))

(defun tess-linkify-region (start end) "Wrap the text from START to END in an HTML A element." (interactive "r") (let ((str (buffer-substring-no-properties start end))) (delete-region start end) (insert "<a href="">" str "")))

;;; nxml (when (or (load "rng-auto" t) (locate-library "nxml-mode"))

(unless (fboundp 'nxml-mode) (autoload 'nxml-mode "nxml-mode" nil t))

(unless (fboundp 'rng-validate-mode) (autoload 'rng-validate-mode "rng-valid" nil t))

(setq tess-xml-mode 'nxml-mode) ;; (setq tess-html-mode 'nxml-mode)

(setq nxml-sexp-element-flag t nxml-slash-auto-complete-flag t)

;; Hack ;' in nxml mode to automatically fix named character entity ;; references. (defun tess-nxml-semicolon-dwim (&rest ignore) "If we've just typed an HTML 4 named character entity reference, replace it with its numerical equivalent. Otherwise, just insert ;'." (interactive) (or (tess-numericalize-entity) (insert ";")))

(when (boundp 'nxml-mode-abbrev-table) (add-hook 'nxml-mode-hook (lambda () (setq local-abbrev-table nxml-mode-abbrev-table))))

(eval-after-load "nxml-mode" '(progn (define-key nxml-mode-map (kbd "") 'tess-linkify-region) (define-key nxml-mode-map (kbd "RET") 'newline-and-indent) ;; Install my `;' hack. (define-key nxml-mode-map (kbd ";") 'tess-nxml-semicolon-dwim))))

Web Development〉=
(add-to-list 'auto-mode-alist
             (cons "\.bs\'" tess-html-mode))
(add-to-list 'auto-mode-alist
             (cons "\.\(x?html\|xht\)\'" tess-html-mode))
(add-to-list 'auto-mode-alist
             (cons "\.\(jsp\|tpl\|tag\)\'" tess-html-mode))
(add-to-list 'auto-mode-alist
             (cons "\.\(wsd[dl]\|tld\|xslt\|plist\)\'"
                   tess-xml-mode))

Web Development〉=
(let ((html5-lib "/code/html5-el/"))
  (when (file-directory-p html5-lib)
    (add-to-list 'load-path html5-lib)
    (eval-after-load "rng-loc"
      '(add-to-list 'rng-schema-locating-files
                    "/code/html5-el/schemas.xml"))
    (require 'whattf-dt nil t)))

Web Development〉=
(defvar tess-html4-link-relations
  '("alternate" "stylesheet" "start" "next" "prev" "contents" "index"
    "glossary" "copyright" "chapter" "section" "subsection" "appendix"
    "help" "bookmark")
  "http://www.w3.org/TR/html4/types.html#type-links")

(defvar tess-html5-link-relations '("alternate" "archives" "author" "bookmark" "contact" "external" "feed" "first" "help" "icon" "index" "last" "license" "next" "nofollow" "pingback" "prefetch" "prev" "search" "stylesheet" "sidebar" "tag" "up") "http://www.whatwg.org/specs/web-apps/current-work/#linkTypes")

(defvar tess-atom-link-relations '(;; http://atompub.org/rfc4287.html#rel_attribute "alternate" "related" "self" "enclosure" "via" ;; http://www.iana.org/assignments/link-relations/ "current" "edit" "edit-media" "first" "last" "next" "next" "payment" "prev" "previous") "")

(defvar tess-xfn-link-relations '("contact" "acquaintance" "friend" ; Friendship "met" ; Physical "co-worker" "colleague" ; Professional "co-resident" "neighbor" ; Geographical "child" "parent" "sibling" "spouse" "kin" ; Family "muse" "crush" "date" "sweetheart" ; Romantic "me") ; Identity "http://gmpg.org/xfn/11")

(defvar tess-uf-link-relations '("license" ; http://microformats.org/wiki/rel-license "nofollow" ; http://microformats.org/wiki/rel-nofollow "tag" ; http://microformats.org/wiki/rel-tag ;; Drafts "directory" ; http://microformats.org/wiki/rel-directory "enclosure" ; http://microformats.org/wiki/rel-enclosure "home" ; http://microformats.org/wiki/rel-home "payment" ; http://microformats.org/wiki/rel-payment ;; Exploratory "cite" ; http://microformats.org/wiki/distributed-conversation-brainstorming "group" ; http://microformats.org/wiki/group-brainstorming "product" ; http://microformats.org/wiki/rel-product "profile") ; http://microformats.org/wiki/xmdp-brainstorming#linking_to_the_XMDP "")

(defvar tess-custom-link-relations '("http://tess.oconnor.cx/link-relations/include" "http://tess.oconnor.cx/link-relations/legacy" "http://tess.oconnor.cx/link-relations/listening" "http://tess.oconnor.cx/link-relations/livejournal" "http://tess.oconnor.cx/link-relations/pingback" "http://tess.oconnor.cx/link-relations/reddit" "http://tess.oconnor.cx/link-relations/stylesheet") "http://tess.oconnor.cx/link-relations/")

(defvar tess-link-relations (seq-uniq (sort (append tess-html4-link-relations tess-html5-link-relations tess-atom-link-relations tess-xfn-link-relations tess-uf-link-relations tess-custom-link-relations) 'string<)) "List of Atom and HTML link relations.")

(defun tess-read-link-relation () "Read a link relation from the user, with completion." (interactive) (completing-read "Link relation: " tess-link-relations nil t))

(defun tess-read-link-relations () "Read link relations from the user until they hit RET." (interactive) (let ((relations '()) (relation (tess-read-link-relation))) (if (equal relation "me") relation (while (not (equal relation "")) (push relation relations) (setq relation (tess-read-link-relation))) (mapconcat (lambda (x) x) (sort relations 'string<) " "))))

(define-skeleton tess-rel-expand "Expand @rel." nil "rel="" (tess-read-link-relations) """)

(defun tess-nuke-nofollow () (interactive) (save-excursion (goto-char (point-min)) (while (re-search-forward "\s-*rel=["']nofollow["']" nil t) (replace-match ""))))

abbrev-definitions〉=
(define-abbrev-table 'nxml-mode-abbrev-table '(
    ("rel" "" tess-rel-expand 0)
    ))

sgml faces〉=
'(sgml-namespace-face ((t (〈keyword face〉))))

defun hober2-use-underline-p〉=
(if (fboundp 'display-supports-face-attributes-p)
    (defun hober2-use-underline-p (&optional display)
      "Non-nil if DISPLAY supports underlining.
This is only sometimes accurate."
      (display-supports-face-attributes-p '(:underline) display))
  (defalias 'hober2-use-underline-p 'window-system))

rng faces〉=
'(rng-error ((t ,(if (hober2-use-underline-p)
                    '(:underline "red")
                  '(〈error face〉)))))

html helper faces〉=
'(html-helper-bold-face ((t ())))
'(html-helper-italic-face ((t ())))
'(html-helper-underline-face ((t ())))
'(html-helper-strikethrough-face ((t ())))
'(html-helper-link-face ((t ())))
'(html-helper-significant-tag-face ((t (:foreground "〈medium cyan〉"))))

nxml faces〉=
'(nxml-text ((t ())))
'(nxml-text-face ((t ())))

'(nxml-attribute-colon ((t (:foreground "〈dark yellow〉")))) '(nxml-attribute-colon-face ((t (:foreground "〈dark yellow〉")))) '(nxml-attribute-local-name ((t (:foreground "〈dark yellow〉")))) '(nxml-attribute-local-name-face ((t (:foreground "〈dark yellow〉")))) '(nxml-attribute-prefix ((t (:foreground "〈dark yellow〉")))) '(nxml-attribute-prefix-face ((t (:foreground "〈dark yellow〉")))) '(nxml-attribute-value ((t (〈string face〉)))) '(nxml-attribute-value-face ((t (〈string face〉)))) '(nxml-attribute-value-delimiter ((t (〈string face〉)))) '(nxml-attribute-value-delimiter-face ((t (〈string face〉)))) '(nxml-cdata-section-CDATA ((t (:foreground "〈medium cyan〉")))) '(nxml-cdata-section-CDATA-face ((t (:foreground "〈medium cyan〉")))) '(nxml-cdata-section-content ((t ()))) '(nxml-cdata-section-content-face ((t ()))) (nxml-cdata-section-delimiter ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) (nxml-cdata-section-delimiter-face ((t 〈dim this face when appropriate〉))) '(nxml-char-ref-delimiter ((t (〈variable face〉)))) '(nxml-char-ref-delimiter-face ((t (〈variable face〉)))) '(nxml-char-ref-number-face ((t (〈variable face〉)))) '(nxml-comment-content ((t (〈comment face〉)))) '(nxml-comment-content-face ((t (〈comment face〉)))) '(nxml-comment-delimiter ((t (〈comment delimiter face〉)))) '(nxml-comment-delimiter-face ((t (〈comment delimiter face〉)))) '(nxml-element-colon ((t (〈keyword face〉)))) '(nxml-element-colon-face ((t (〈keyword face〉)))) '(nxml-element-local-name ((t (:foreground "〈medium cyan〉")))) '(nxml-element-local-name-face ((t (:foreground "〈medium cyan〉")))) '(nxml-element-prefix ((t (〈keyword face〉)))) '(nxml-element-prefix-face ((t (〈keyword face〉)))) '(nxml-entity-ref-delimiter ((t (〈variable face〉)))) '(nxml-entity-ref-delimiter-face ((t (〈variable face〉)))) '(nxml-entity-ref-name ((t (〈variable face〉)))) '(nxml-entity-ref-name-face ((t (〈variable face〉)))) (nxml-markup-declaration-delimiter ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) (nxml-markup-declaration-delimiter-face ((t 〈dim this face when appropriate〉))) '(nxml-namespace-attribute-colon ((t (:foreground "〈dark yellow〉")))) '(nxml-namespace-attribute-colon-face ((t (:foreground "〈dark yellow〉")))) '(nxml-namespace-attribute-prefix ((t (:foreground "〈dark yellow〉")))) '(nxml-namespace-attribute-prefix-face ((t (:foreground "〈dark yellow〉")))) '(nxml-namespace-attribute-xmlns ((t (:foreground "〈dark yellow〉")))) '(nxml-namespace-attribute-xmlns-face ((t (:foreground "〈dark yellow〉")))) '(nxml-processing-instruction-content-face ((t ()))) (nxml-processing-instruction-delimiter-face ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) '(nxml-processing-instruction-target ((t (:foreground "〈<a href='#dark-cyan'>dark cyan</a>〉")))) '(nxml-processing-instruction-target-face ((t (:foreground "〈<a href='#dark-cyan'>dark cyan</a>〉")))) '(nxml-prolog-keyword ((t (:foreground "〈<a href='#medium-cyan'>medium cyan</a>〉")))) '(nxml-prolog-keyword-face ((t (:foreground "〈<a href='#medium-cyan'>medium cyan</a>〉")))) '(nxml-prolog-literal-content ((t (〈<a href='#string-face'>string face</a>〉)))) '(nxml-prolog-literal-content-face ((t (〈<a href='#string-face'>string face</a>〉)))) '(nxml-prolog-literal-delimiter ((t (〈<a href='#string-face'>string face</a>〉)))) '(nxml-prolog-literal-delimiter-face ((t (〈<a href='#string-face'>string face</a>〉)))) (nxml-tag-delimiter ((t 〈dim this face when appropriate〉))) (nxml-tag-delimiter-face ((t 〈<a href='#dim-this-face-when-appropriate'>dim this face when appropriate</a>〉))) (nxml-tag-slash ((t 〈dim this face when appropriate〉))) `(nxml-tag-slash-face ((t 〈dim this face when appropriate〉)))

;; (nxml-heading ((t ()))) ;; (nxml-heading-face ((t ()))) ;; (nxml-outline-indicator ((t ()))) ;; (nxml-outline-indicator-face ((t ()))) ;; (nxml-outline-active-indicator ((t ()))) ;; (nxml-outline-active-indicator-face ((t ()))) ;; (nxml-outline-ellipsis ((t ()))) ;; (nxml-outline-ellipsis-face ((t ()))) ;; (nxml-delimited-data ((t ()))) ;; (nxml-delimited-data-face ((t ()))) ;; (nxml-name ((t ()))) ;; (nxml-name-face ((t ()))) ;; (nxml-ref ((t ()))) ;; (nxml-ref-face ((t ()))) ;; (nxml-delimiter ((t ()))) ;; (nxml-delimiter-face ((t ()))) ;; (nxml-namespace-attribute-value ((t ()))) ;; (nxml-namespace-attribute-value-face ((t ()))) ;; (nxml-namespace-attribute-value-delimiter ((t ()))) ;; (nxml-namespace-attribute-value-delimiter-face ((t ()))) ;; (nxml-hash ((t ()))) ;; (nxml-hash-face ((t ()))) ;; (nxml-glyph ((t ()))) ;; (nxml-glyph-face ((t ())))

html template〉=
(let ((html-template "template.html"))
  (when (file-exists-p (expand-file-name html-template
                                         auto-insert-directory))
    (add-to-list 'auto-insert-alist
                 (("\\.html\\'" . "HTML") . ,html-template)))) </code></pre></figure><figure id='atom-template'><figcaption>〈<a href='#atom-template'>atom template</a>〉=</figcaption><pre><code>(let ((atom-template "template.atom"))   (when (file-exists-p (expand-file-name atom-template                                          auto-insert-directory))     (add-to-list 'auto-insert-alist                  (("\.atom\'" . "Atom") . ,atom-template))))
how to use a stylesheet〉=

insert/template.atom〉=

  tag:tess.oconnor.cx,2022-MM-DD:slug

Theresa O’Connor hober0@gmail.com http://tess.oconnor.cx/
insert/template.html〉=




tess-unescape-html

Web Development〉=
(defun tess-unescape-html (start end)
  (interactive "r")
  (save-excursion
    (goto-char start)
    (while (re-search-forward "&\\(lt\\|gt\\|quot\\|amp\\);" end t)
      (let* ((entities '(("quot" . "\"") ("amp" . "&")
                         ("lt" . "<") ("gt" . ">")))
             (replacement (assoc (match-string 1) entities)))
        (when replacement
          (replace-match (cdr replacement)))))))

editing html entities

Web Development〉=
(defvar tess-html4-intrinsic-events
  '("load" "unload" "click" "dblclick" "mousedown" "mouseup" "mouseover"
    "mousemove" "mouseout" "focus" "blur" "keypress" "keydown" "keyup"
    "submit" "reset" "select" "change")
  "HTML4 intrinsic events.")

html4 entity map

(defun tess-numericalize-entity () "Replace the named character entity reference at point with its numerical equivalent, if known." (interactive) (let ((end (point)) (start (search-backward "&" (- (point) 7) t))) (when start (if (looking-at "&\([a-z][a-z0-9]+\)") (let* ((name (match-string 1)) (num (cdr (assoc name tess-html4-entity-map)))) (if num (progn (delete-region start end) (insert (format "&#%s;" num)) t) (goto-char end) nil)) (goto-char end) nil))))

htmlize

htmlize〉=
(when (locate-library "htmlize")
  (autoload 'htmlize-buffer "htmlize" nil t))

tess-htmlize〉=
(defun tess-stringify-face-name (face)
  "Blah blah blah."
  (when (listp face)
    (setq face (car (last face))))
  (let ((name (if (symbolp face) (symbol-name face) face)))
    (if (string-match "^\(font-lock-\)?\(.+?\)\(-name\)?\(-face\)?$" ; $
                      name)
        (match-string 2 name)
      name)))

(defvar tess-htmlize-face-translation-map '(;; I don't want to highlight parens in lisp (paren-face . nil) ;; Parts of X{,HT}ML I don't want to highlight (nxml-tag-delimiter . nil) (nxml-tag-delimiter-face . nil) (nxml-tag-slash . nil) (nxml-tag-slash-face . nil) (nxml-text . nil) (nxml-text-face . nil) ;; CSS (css-property . font-lock-function-name-face) ;; Map nXML faces onto standard font-lock faces (nxml-attribute-value-delimiter . font-lock-string-face) (nxml-attribute-value-delimiter-face . font-lock-string-face) (nxml-attribute-value . font-lock-string-face) (nxml-attribute-value-face . font-lock-string-face) (nxml-attribute-local-name . font-lock-builtin-face) (nxml-attribute-local-name-face . font-lock-builtin-face) (nxml-element-local-name . font-lock-keyword-face) (nxml-element-local-name-face . font-lock-keyword-face) ;; Makefiles (makefile-targets . font-lock-function-name-face) (makefile-shell . nil) ;; MML tags should look like types (message-mml-face . font-lock-type-face) (message-mml . font-lock-type-face)) "Blah blah blah")

(defun tess-htmlize-face-at-point (&optional pos) "Blah blah blah." (unless pos (setq pos (point))) (let* ((face (get-text-property pos 'face)) (translation (member* face tess-htmlize-face-translation-map :key 'car))) (if translation (cdar translation) face)))

(defun tess-htmlize-region (start end) "Place an htmlized version of the region into the kill ring." (interactive "r") (let ((code (buffer-substring start end)) (language (substring (symbol-name major-mode) 0 -5)) current-face) (with-temp-buffer (fundamental-mode) (font-lock-mode -1)

  (insert code)

  (goto-char (point-min))

  (setq current-face (tess-htmlize-face-at-point))
  (insert (format "<pre><code class=\"%s\">" language))
  (when current-face
    (insert (format "<span class=\"%s\">"
                    (tess-stringify-face-name current-face))))

  (let (n-p-c)
    (while (setq n-p-c (next-property-change (point)))
      (goto-char n-p-c)
      (cond
       ((and current-face (eq current-face (tess-htmlize-face-at-point))))
       ((and current-face (null (tess-htmlize-face-at-point)))
        (insert "</span>")
        (setq current-face nil))
       ((and current-face (tess-htmlize-face-at-point))
        (insert "</span>")
        (setq current-face (tess-htmlize-face-at-point))
        (when current-face
          (insert (format "<span class=\"%s\">"
                          (tess-stringify-face-name current-face)))))
       ((tess-htmlize-face-at-point)
        (setq current-face (tess-htmlize-face-at-point))
        (when current-face
          (insert (format "<span class=\"%s\">"
                          (tess-stringify-face-name current-face))))))))
  (goto-char (point-max))
  (insert "</code></pre>")
  (setq code (buffer-substring-no-properties (point-min) (point-max))))
(kill-new code)))

Web Development〉=
(setq html-tag-face-alist
      '(("b" . bold)
        ("big" . bold)
        ("blink" . highlight)
        ("h1" bold underline)
        ("h4" . underline)
        ("h5" . underline)
        ("h6" . underline)
        ("rev"  . modeline)
        ("s" . underline)
        ("small" . default)
        ("strong" . bold)
        ("title" bold underline)
        ("tt" . default)
        ("u" . underline)
        ;; Were italic
        ("cite" . default)
        ("em" . bold)
        ("h2" bold underline)
        ("h3" underline)
        ("i" . italic)
        ("var" . default)))

CSS

css-mode.el fetch rule〉=
css-mode.el:
        curl -O http://www.garshol.priv.no/download/software/css-mode/css-mode.el
Web Development〉=
(when (locate-library "css-mode")
  (autoload 'css-mode "css-mode" nil t)
  (add-to-list 'auto-mode-alist '("\\.css\\'" . css-mode))
  〈customize each css mode〉)

customize each css mode〉=
(eval-after-load "css-mode"
  '(cond ((boundp 'cssm-indent-function) ; larsga's css-mode.el
            〈larsga css-mode.el customizations〉)
           ((fboundp 'css-extract-keyword-list) ; monnier's css-mode.el
            〈monnier css-mode.el customizations〉)
    (t nil)))
css-mode (monnier) faces〉=
'(css-selector ((t (:foreground "〈medium red〉"))))
'(css-property ((t (:foreground "〈light cyan〉"))))
'(css-proprietary-property ((t (:foreground "〈light cyan〉"))))

monnier css-mode.el customizations〉=
(setq css-basic-offset 2
      css-indent-offset 2)
larsga css-mode.el customizations〉=
(add-hook 'css-mode-hook
          (lambda ()
            (setq cssm-mirror-mode nil
                  cssm-newline-before-closing-bracket nil
                  cssm-indent-function 'cssm-c-style-indenter)))
css template〉=
(let ((css-template "template.css"))
  (when (file-exists-p (expand-file-name css-template
                                         auto-insert-directory))
    (add-to-list 'auto-insert-alist
                 `(("\.css\'" . "CSS") . ,css-template))))

insert/template.css〉=
body {
}

RSS and Atom

Web Development〉=
(add-to-list 'auto-mode-alist
             (cons "\\.\\(rdf\\|rss\\|atom\\)\\'" tess-xml-mode))

.quickurls〉=
;;; .quickurls --- Theresa O'Connor's quick urls -- emacs-lisp --
;; 〈Copyright〉
(("AB"      . "https://www.w3.org/2002/ab/")
 ("AC"      . "https://www.w3.org/wiki/AdvisoryCommittee")
 ("Alice"   . "https://twitter.com/sundress")
 ("Apple"   . "https://apple.com/")
 ("Bryan"   . "https://twitter.com/rafuzo")
 ("CSSWG"   . "https://www.w3.org/Style/CSS/")
 ("EJ"      . "http://ej.oconnor.cx/")
 ("Erin"    . "http://erin.oconnor.cx/")
 ("Eryn"    . "https://erynwells.me/")
 ("GitHub"  . "https://github.com/")
 ("Jer"     . "https://jernoble.com/")
 ("Lindsay" . "https://twitter.com/lindsaydayton")
 ("PING"    . "https://www.w3.org/Privacy/IG/")
 ("TAG"     . "https://www.w3.org/2001/tag/")
 ("W3C"     . "https://www.w3.org/")
 ("WebKit"  . "https://webkit.org/")
 ("WHATWG"  . "https://whatwg.org/"))
Use Emacs' quickurls from PowerShell〉=
class Hyperlink {
    [string]$Name
    [uri]$Link

Hyperlink([string]$Name,[uri]$Link) {
    $this.Name = $Name
    $this.Link = $Link
}

[String]ToAnsiString() {
    return ("`e]8;;{1}`e\{0}`e]8;;`e\" -f $this.Name,$this.Link) #"
}

[String]ToHTML() {
    return ('<a href="{1}">{0}</a>' -f $this.Name,$this.Link)
}

[String]ToMarkdown() {
    return ('[{0}]({1})' -f $this.Name,$this.Link)
}

[String]ToString() {
    return ('{0} <{1}>' -f $this.Name,$this.Link)
}

}

function Get-Quickurl { [CmdletBinding()] param( [Parameter(Position=0)] [string]$Name )

$quickurl_re = '^\s*\({1,2}"([^"]+)"\s*[.]\s*"([^"]+)"\){1,2}$'

foreach ($Line in Get-Content (Join-Path '~' '.quickurls')) {
    if ($Line -match $quickurl_re) {
        $Link=[Hyperlink]::new($Matches.1,[uri]$Matches.2)

        if ($PSBoundParameters.ContainsKey('Name')) {
            if ($Link.Name -like $Name) {
                $Link
            }
        } else {
            $Link
        }
    }
}

}

Set-Alias -Name gqu -Value Get-Quickurl

function Show-Quickurl { [CmdletBinding()] param( [Parameter(Position=0,Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [switch]$PassThru=$false )

$quickurl = Get-Quickurl $Name

foreach ($qu in $quickurl) {
    if ($IsWindows) {
        start $qu.link.absoluteuri
    } elseif ($IsMacOS) {
        open $qu.link.absoluteuri
    } elseif ($IsLinux) {
        xdg-open $qu.link.absoluteuri
    }
}

if ($PassThru) {
    $quickurl
}

}

Set-Alias -Name shqu -Value Show-Quickurl

Spec writing

Markdown

markdown-mode faces〉=
'(markdown-italic-face ((t (:inherit italic))))
'(markdown-bold-face ((t (:inherit bold))))
'(markdown-strike-through-face ((t (:strike-through t))))
'(markdown-markup-face ((t (:inherit shadow :slant normal :weight normal))))
'(markdown-header-rule-face ((t (:inherit markdown-markup-face))))
'(markdown-header-delimiter-face ((t (:inherit markdown-markup-face))))
'(markdown-list-face ((t (:inherit markdown-markup-face))))
'(markdown-blockquote-face ((t (〈string face (alt)〉))))
'(markdown-code-face ((t (:inherit fixed-pitch))))
'(markdown-inline-code-face ((t (:inherit (markdown-code-face
                                           font-lock-constant-face)))))
'(markdown-pre-face ((t (:inherit (markdown-code-face
                                   font-lock-constant-face)))))
'(markdown-table-face ((t (:inherit (markdown-code-face)))))
'(markdown-language-keyword-face ((t (〈keyword face〉))))
'(markdown-language-info-face ((t (〈string face〉))))
'(markdown-link-face ((t (:inherit link))))
'(markdown-missing-link-face ((t (〈warning face〉))))
'(markdown-reference-face ((t (:inherit markdown-markup-face))))
'(markdown-footnote-marker-face ((t (:inherit markdown-markup-face))))
'(markdown-footnote-text-face ((t (〈comment face〉))))
'(markdown-url-face ((t (〈string face〉))))
'(markdown-plain-url-face ((t (:inherit markdown-link-face))))
'(markdown-link-title-face ((t (〈comment face〉))))
'(markdown-line-break-face ((t (〈constant face〉 :underline t))))
'(markdown-comment-face ((t (〈comment face〉))))
'(markdown-math-face ((t (〈string face〉))))
'(markdown-metadata-key-face ((t (〈variable face〉))))
'(markdown-metadata-value-face ((t (〈string face〉))))
'(markdown-gfm-checkbox-face ((t (〈builtin face〉))))
'(markdown-highlight-face ((t (:inherit highlight))))
'(markdown-hr-face ((t (:inherit markdown-markup-face))))
'(markdown-html-tag-name-face ((t (〈function face〉))))
'(markdown-html-tag-delimiter-face ((t (:inherit markdown-markup-face))))
'(markdown-html-attr-name-face ((t (〈variable face〉))))
'(markdown-html-attr-value-face ((t (〈string face〉))))
'(markdown-html-entity-face ((t (〈variable face〉))))

Editing Markdown files〉=
(add-to-list 'auto-mode-alist '("\.md\'" . markdown-mode))

(add-hook 'markdown-mode-hook 'turn-off-auto-fill) (add-hook 'markdown-mode-hook (lambda () (setq fill-column most-positive-fixnum))) (add-hook 'markdown-mode-hook (lambda () (visual-line-mode 1)))

(add-hook 'markdown-mode-hook (lambda () (define-key markdown-mode-map (kbd "<") 'self-insert-command)))

(setq markdown-command (seq-find 'executable-find '("marked markdown2")))

(when (eq system-type 'darwin) (defconst tess-markdown-previewers '("Marked 2" "Marked"))

(defconst tess-markdown-previewer (and (executable-find "oa") (seq-find (lambda (app) (= 0 (call-process "oa" nil nil nil "-dq" app))) tess-markdown-previewers)))

(eval-after-load "markdown-mode" '(defun markdown-open () "Open file for the current buffer." (interactive) (unless buffer-file-name (user-error "Must be visiting a file")) (unless tess-markdown-previewer (user-error "No Markdown previewer found")) (call-process "open" nil nil nil "-a" tess-markdown-previewer buffer-file-name))))

Bikeshed

Editing Bikeshed files〉=
(add-to-list 'auto-mode-alist '("\\.bs\\'" . bikeshed-mode))

RFCs

rfcview〉=
(when (locate-library "rfcview")
  (autoload 'rfcview-mode "rfcview" nil t)
  (add-to-list 'auto-mode-alist '("rfc[0-9]+\\.txt" . rfcview-mode)))

Relax-NG

Web Development〉=
;;; editing relax-ng compact schema
(when (locate-library "rnc-mode")
  (autoload 'rnc-mode "rnc-mode" nil t)
  (add-to-list 'auto-mode-alist '("\\.rnc\\'" . rnc-mode)))

Programming

comment style

comment-style〉=
(setq comment-style 'indent)

fillcode.el

fillcode.el fetch rule〉=
fillcode.el:
        curl -O http://snarfed.org/space/fillcode/fillcode.el

shell mode faces

shell faces〉=
'(sh-heredoc-face ((t (〈string face (alt)〉))))
'(sh-quoted-exec ((t (〈string face (alt)〉))))

glasses-mode

Configuring glasses-mode〉=
(setq glasses-separator           "-"
      glasses-uncapitalize-regexp ".*"
      glasses-uncapitalize-p      t)
### paredit
paredit.el fetch rule〉=
paredit.el:
        curl -O http://mumble.net/~campbell/emacs/paredit.el
Programming Utilities〉=
(ignore-errors (require 'paredit))

skeleton pairs

Make paired characters electric〉=
(setq skeleton-pair t)
(global-set-key "[" 'skeleton-pair-insert-maybe)
(global-set-key "{" 'skeleton-pair-insert-maybe)
(global-set-key "\"" 'skeleton-pair-insert-maybe)

syntax highlighting

Enable Font Locking〉=
(require 'font-lock)

(setq font-lock-maximum-size most-positive-fixnum)

(when (fboundp 'global-font-lock-mode) (defun tess-enable-font-lock-globally () (global-font-lock-mode 1)) (add-hook 'tess-after-local-init-hook 'tess-enable-font-lock-globally))

(when (fboundp 'toggle-global-lazy-font-lock-mode) (add-hook 'tess-after-local-init-hook 'toggle-global-lazy-font-lock-mode))

builtin face〉=
:foreground "〈dark yellow〉"
font lock faces〉=
'(font-lock-builtin-face ((t (〈builtin face〉))))
'(font-lock-color-constant-face ((t (:foreground "〈medium yellow〉"))))
'(font-lock-comment-face ((t (〈comment face〉))))
'(font-lock-comment-delimiter-face ((t (〈comment delimiter face〉))))
constant face〉=
:foreground "〈light magenta〉"
font lock faces〉=
'(font-lock-constant-face ((t (〈constant face〉))))
font lock faces〉=
'(font-lock-doc-face ((t (〈string face (alt)〉))))
font lock faces〉=
'(font-lock-doc-string-face ((t (〈comment face (alt)〉))))
string face〉=
:foreground "〈light yellow〉"
string face (alt)〉=
:foreground "〈medium yellow〉"
variable face〉=
:foreground "〈light red〉"
variable face (alt)〉=
:foreground "〈medium red〉"
function face〉=
:foreground "〈medium cyan〉"
keyword face〉=
:foreground "〈dark cyan〉"
type face〉=
:foreground "〈medium green〉"
font lock faces〉=
'(font-lock-function-name-face ((t (〈function face〉))))
'(font-lock-keyword-face ((t (〈keyword face〉))))
'(font-lock-preprocessor-face ((t (:foreground "〈medium yellow〉"))))
'(font-lock-reference-face ((t (:foreground "〈medium yellow〉"))))
'(font-lock-string-face ((t (〈string face〉))))
'(font-lock-type-face ((t (〈type face〉))))
'(font-lock-variable-name-face ((t (〈variable face〉))))
'(font-lock-warning-face ((t (〈warning face〉))))

CamelCase-aware stuff

CamelCase-aware killing functions〉=
(defun tess-c-kill-backwards-into-nomenclature ()
  "Delete the CamelCase word before point."
  (interactive)
  (let ((end (point)))
    (c-backward-into-nomenclature 1)
    (kill-region (point) end)))

(defun tess-c-kill-forwards-into-nomenclature () "Delete the CamelCase word after point." (interactive) (let ((beg (point))) (c-forward-into-nomenclature 1) (kill-region beg (point))))

(let ((hooks '(c-mode-common-hook espresso-mode-hook js-mode-hook js2-mode-hook python-mode-hook swift-mode-hook)) (enable-subword-bindings (cond ((fboundp 'subword-mode) (lambda () (subword-mode 1))) ((fboundp 'c-subword-mode) (lambda () (c-subword-mode 1))) (t (lambda () (local-set-key (kbd "M-DEL") 'tess-c-kill-backwards-into-nomenclature) (local-set-key (kbd "M-d") 'tess-c-kill-forwards-into-nomenclature)))))) (mapc (lambda (hook) (add-hook hook enable-subword-bindings)) hooks))

Change Logs

change-log-default-name〉=
(setq change-log-default-name "ChangeLog")

change log faces〉=
'(change-log-date-face ((t (:foreground "〈light yellow〉"))))
'(change-log-name-face ((t (:foreground "〈medium yellow〉"))))
'(change-log-email-face ((t (:foreground "〈medium red〉"))))
'(change-log-file-face ((t (〈filename face〉))))
'(change-log-list-face ((t (:foreground "〈medium blue〉"))))
'(change-log-conditionals-face ((t (:foreground "〈medium red〉"))))
'(change-log-function-face ((t (:foreground "〈medium red〉"))))
'(change-log-acknowledgement-face ((t (〈cyan bg〉 〈dark fg〉))))

Diff, ediff, emerge, smerge

Programming Utilities〉=
(setq diff-switches "-u")

Programming Utilities〉=
(autoload 'diff-context->unified "diff-mode" nil t)
(autoload 'diff-unified->context "diff-mode" nil t)

diff faces〉=
'(diff-added ((t (〈default bg〉 :foreground "〈medium green〉"))))
'(diff-changed ((t (〈default bg〉 :foreground "〈medium green〉"))))
'(diff-context ((t (〈default bg〉 〈default fg〉))))
'(diff-file-header ((t (〈default bg (alt)〉 〈default fg〉 :bold t))))
'(diff-function ((t (〈default bg (alt)〉 〈default fg (alt)〉))))
'(diff-header ((t (〈default bg (alt)〉 〈default fg (alt)〉))))
'(diff-hunk-header ((t (〈default bg〉 〈default fg (alt)〉))))
'(diff-index ((t (〈default bg〉 〈default fg〉 :bold t))))
'(diff-indicator-added ((t (〈default bg〉 :foreground "〈medium green〉"))))
'(diff-indicator-changed ((t (〈default bg〉 :foreground "〈medium yellow〉"))))
'(diff-indicator-removed ((t (〈default bg〉 :foreground "〈medium red〉"))))
'(diff-nonexistent ((t (〈warning face〉))))
'(diff-removed ((t (〈default bg〉 :foreground "〈medium red〉"))))

smerge-mode faces〉=
'(smerge-refined-change ((t (:background "〈medium black〉"))))

smerge-mode〉=
(setq smerge-command-prefix (kbd "C-c s"))
ediff bg ancestor〉=
:background "〈light red〉"
ediff bg b〉=
:background "〈light yellow〉"
ediff bg c〉=
:background "〈medium green〉"
ediff faces〉=
'(ediff-current-diff-face-A ((t (〈cyan bg〉 〈dark fg〉))))
'(ediff-current-diff-face-Ancestor ((t (〈ediff bg ancestor〉
                                        〈dark fg〉))))
'(ediff-current-diff-face-B ((t (〈ediff bg b〉 〈dark fg (alt)〉))))
'(ediff-current-diff-face-C ((t (〈ediff bg c〉
                                 〈dark fg〉))))
'(ediff-even-diff-face-A ((t (〈cyan bg〉 〈dark fg〉 :bold t))))
'(ediff-even-diff-face-Ancestor ((t (〈ediff bg ancestor〉
                                     〈dark fg〉
                                     :bold t))))
'(ediff-even-diff-face-B ((t (〈ediff bg b〉 〈dark fg (alt)〉
                              :bold t))))
'(ediff-even-diff-face-C ((t (〈ediff bg c〉 〈dark fg〉
                              :bold t))))
'(ediff-fine-diff-face-A ((t (〈cyan bg (alt)〉 〈dark fg〉))))
'(ediff-fine-diff-face-Ancestor ((t (:background "〈dark red〉"
                                     〈dark fg〉))))
'(ediff-fine-diff-face-B ((t (〈region face (alt)〉))))
'(ediff-fine-diff-face-C ((t (:background "〈dark green〉"
                              〈dark fg〉))))
'(ediff-odd-diff-face-A ((t (〈cyan bg (alt)〉 〈dark fg〉
                             :bold t))))
'(ediff-odd-diff-face-Ancestor ((t (:background "〈dark red〉"
                                    〈dark fg〉
                                    :bold t))))
'(ediff-odd-diff-face-B ((t (〈region face (alt)〉 :bold t))))
'(ediff-odd-diff-face-C ((t (:background "〈dark green〉"
                             〈dark fg〉 :bold t))))
'(ediff-current-diff-A ((t (〈cyan bg〉 〈dark fg〉))))
'(ediff-current-diff-Ancestor ((t (〈ediff bg ancestor〉
                                        〈dark fg〉))))
'(ediff-current-diff-B ((t (〈ediff bg b〉 〈dark fg (alt)〉))))
'(ediff-current-diff-C ((t (〈ediff bg c〉
                                 〈dark fg〉))))
'(ediff-even-diff-A ((t (〈cyan bg〉 〈dark fg〉 :bold t))))
'(ediff-even-diff-Ancestor ((t (〈ediff bg ancestor〉
                                     〈dark fg〉
                                     :bold t))))
'(ediff-even-diff-B ((t (〈ediff bg b〉 〈dark fg (alt)〉
                              :bold t))))
'(ediff-even-diff-C ((t (〈ediff bg c〉 〈dark fg〉
                              :bold t))))
'(ediff-fine-diff-A ((t (〈cyan bg (alt)〉 〈dark fg〉))))
'(ediff-fine-diff-Ancestor ((t (:background "〈dark red〉"
                                     〈dark fg〉))))
'(ediff-fine-diff-B ((t (〈region face (alt)〉))))
'(ediff-fine-diff-C ((t (:background "〈dark green〉"
                              〈dark fg〉))))
'(ediff-odd-diff-A ((t (〈cyan bg (alt)〉 〈dark fg〉
                             :bold t))))
'(ediff-odd-diff-Ancestor ((t (:background "〈dark red〉"
                                    〈dark fg〉
                                    :bold t))))
'(ediff-odd-diff-B ((t (〈region face (alt)〉 :bold t))))
'(ediff-odd-diff-C ((t (:background "〈dark green〉"
                             〈dark fg〉 :bold t))))

Version Control

Subversion

.subversion/config〉=
[miscellany]
interactive-conflicts = no

psvn.el fetch rule〉=
psvn.el:
        curl -O http://www.xsteve.at/prg/emacs/psvn.el
psvn〉=
(autoload 'svn-status "psvn" nil t)
psvn faces〉=
'(svn-status-marked-face ((t (〈marked face〉))))
'(svn-status-marked-popup-face ((t (〈error face〉))))
'(svn-status-update-available-face ((t (〈warning face〉))))
'(svn-status-directory-face ((t (〈directory face〉))))
'(svn-status-filename-face ((t (〈filename face〉))))
'(svn-status-symlink-face ((t (〈symlink face〉))))
'(svn-status-locked-face ((t (〈comment face〉))))
'(svn-status-switched-face ((t (〈string face〉))))
'(svn-status-blame-highlight-face ((t (〈highlight face〉))))
'(svn-status-blame-rev-number-face ((t (〈marked face〉))))

vc-svn.el fetch rule〉=
vc-svn.el:
        curl -O http://www.tug.org/ftp/dist/vc-svn.el
vc-svn〉=
(unless (memq 'SVN vc-handled-backends)
  (add-to-list 'vc-handled-backends 'SVN))

Git

gitsum〉=
(autoload 'gitsum "gitsum" nil t)
Disable pager when git is run from Emacs〉=
(setenv "GIT_PAGER" "cat")

.gitconfig〉=
[user]
name = Theresa O'Connor

Set email in $XDG_CONFIG_HOME/git/config '

[color] diff = auto status = auto branch = auto

[init] defaultBranch = main

[merge] ff = only

[pull] rebase = true autoStash = true

[push] default = matching

github elisp make rules〉=
logito/logito.el:
        git clone https://github.com/sigma/logito.git
pcache/pcache.el:
        git clone https://github.com/sigma/pcache.git
gh.el/gh.el:
        git clone https://github.com/sigma/gh.el.git
gist.el/gist.el:
        git clone https://github.com/defunkt/gist.el
tabulated-list.el/tabulated-list.el:
        git clone https://github.com/sigma/tabulated-list.el

gh.el/gh.elc: gh.el/gh.el pcache/pcache.el logito/logito.el
pcache/pcache.elc logito/logito.elc make -C gh.el lisp EMACS="$(EMACS) -L $(CWD)/pcache -L $(CWD)/logito"

put gist.el and dependencies in load-path〉=
(apply 'tess-add-to-list* 'load-path
       (mapcar 'tess-expand-file-name-in-code-dir
               '("gh.el" "gist.el" "logito" "pcache"
                 "tabulated-list.el")))

gist〉=
(ignore-errors (require 'gist))

vc mode

Programming Utilities〉=
(setq vc-follow-symlinks t)

Languages

SQL

Open PostgreSQL views and source files in sql-mode〉=
(add-to-list 'auto-mode-alist '("\\.view\\'" . sql-mode))
(add-to-list 'auto-mode-alist '("\\.psql\\'" . sql-mode))
Open PostgreSQL views and source files in sql-mode〉=
(setq sql-sqlite-program "sqlite3")

JavaScript

Ensure NODE_PATH is set up properly〉=
if [[ -d '/usr/local/lib/node_modules' && ! -v NODE_PATH ]]; then
    export NODE_PATH='/usr/local/lib/node_modules'
fi

export DENO_INSTALL_ROOT=~/$SYSNAME/bin

js2 faces〉=
'(js2-builtin-face ((t (〈builtin face〉))))
'(js2-comment-face ((t (〈comment face〉))))
'(js2-constant-face ((t (〈constant face〉))))
'(js2-error-face ((t (〈error face〉))))
'(js2-external-variable-face ((t (〈variable face (alt)〉))))
'(js2-function-name-face ((t (〈function face〉))))
'(js2-function-param-face ((t (〈variable face〉))))
'(js2-instance-member-face ((t (〈variable face〉))))
;; Copied from nxml-tag-delimiter' (js2-jsdoc-html-tag-delimiter-face ((t 〈dim this face when appropriate〉)))
;; Copied from `nxml-element-local-name'
'(js2-jsdoc-html-tag-name-face ((t (:foreground "〈medium cyan〉"))))
'(js2-jsdoc-tag-face ((t (〈comment face (alt)〉))))
'(js2-jsdoc-type-face ((t (〈comment face (alt)〉))))
'(js2-jsdoc-value-face ((t (〈comment face (alt)〉))))
'(js2-keyword-face ((t (〈keyword face〉))))
'(js2-private-function-call-face ((t (〈function face〉))))
'(js2-private-member-face ((t (〈variable face〉))))
'(js2-regexp-face ((t (〈string face (alt)〉))))
'(js2-string-face ((t (〈string face〉))))
'(js2-type-face ((t (〈type face〉))))
'(js2-variable-name-face ((t (〈variable face〉))))
'(js2-warning-face ((t (〈warning face〉))))

js template〉=
(let ((js-template "template.js"))
  (when (file-exists-p (expand-file-name js-template
                                         auto-insert-directory))
    (add-to-list 'auto-insert-alist
                 `(("\.js\'" . "JS") . ,js-template))))

insert/template.js〉=
(function () {
})();
moz.el fetch rule〉=
moz.el:
        curl -O http://github.com/bard/mozrepl/raw/master/chrome/content/moz.el
espresso.el fetch rule〉=
espresso.el:
        curl -O http://download.savannah.gnu.org/releases-noredirect/espresso/espresso.el
ecmascript-mode.el fetch rule〉=
ecmascript-mode.el:
        curl -O $(EMACSWIKI_DOWNLOAD)/ecmascript-mode.el
javascript.el fetch rule〉=
javascript.el: javascript.el.zip
        unzip -fo javascript.el.zip
javascript.el.zip:
        curl -O http://web.comhem.se/~u34308910/emacs/javascript.el.zip
js2 config〉=
(autoload 'js2-mode "js2-mode" nil t)
(setq js2-highlight-level 3
      js2-cleanup-whitespace nil
      js2-bounce-indent-p nil
      js2-auto-indent-p nil
      js2-indent-on-enter-key t)
(add-hook 'js2-mode-hook
          (lambda () (setq mode-name "JS2")))
javascript.el config〉=
(setq js-indent-level 4
      javascript-indent-level 4
      javascript-auto-indent-flag nil)
(autoload 'javascript-mode "javascript" nil t)
(when (boundp 'javascript-mode-abbrev-table)
  (add-hook 'javascript-mode-hook
            (lambda ()
              (setq local-abbrev-table javascript-mode-abbrev-table))))
js.el config〉=
(setq js-indent-level 4)
espresso.el config〉=
(autoload 'espresso-mode "espresso" nil t)

(setq espresso-indent-level 4)

Web Development〉=
(defvar tess-javascript-mode 'javascript-generic-mode
  "What major mode should I be using for JavaScript.")

(cond ((locate-library "js") (setq tess-javascript-mode 'js-mode) 〈js.el config〉) ((locate-library "espresso") (setq tess-javascript-mode 'espresso-mode) 〈espresso.el config〉) ((locate-library "js2-mode") (setq tess-javascript-mode 'js2-mode) 〈js2 config〉) ((locate-library "javascript") (setq tess-javascript-mode 'javascript-mode) 〈javascript.el config〉))

(add-to-list 'auto-mode-alist (cons "\.htc\'" tess-javascript-mode)) (add-to-list 'auto-mode-alist (cons "\.m?js\'" tess-javascript-mode)) (add-to-list 'auto-mode-alist (cons "\.json\'" tess-javascript-mode))

abbrev-definitions〉=
(define-abbrev-table 'javascript-mode-abbrev-table '(
    ))

Java and the JDE

jde faces〉=
'(jde-bug-breakpoint-cursor ((t (:background "cyan"))))
'(jde-db-active-breakpoint-face ((t (:background "cyan"))))
'(jde-db-requested-breakpoint-face ((t (:background "cyan"))))
'(jde-db-spec-breakpoint-face ((t (:background "cyan"))))
'(jde-java-font-lock-api-face ((t (:background "cyan"))))
'(jde-java-font-lock-bold-face ((t (:bold t 〈comment face〉))))
'(jde-java-font-lock-code-face ((t (:foreground "〈medium red〉"
                                   〈cyan bg〉))))
'(jde-java-font-lock-constant-face ((t (〈constant face〉))))
'(jde-java-font-lock-doc-tag-face ((t (:foreground "〈medium yellow〉"
                                      〈cyan bg〉))))
'(jde-java-font-lock-italic-face ((t (:slant italic 〈comment face〉))))
'(jde-java-font-lock-link-face ((t (:background "cyan"))))
'(jde-java-font-lock-modifier-face ((t (:foreground "〈medium blue〉"))))
'(jde-java-font-lock-number-face ((t (:foreground "〈medium yellow〉"))))
'(jde-java-font-lock-operator-face ((t (:background "cyan"))))
'(jde-java-font-lock-package-face ((t (:foreground "〈medium yellow〉"))))
'(jde-java-font-lock-pre-face ((t (:background "cyan"))))
'(jde-java-font-lock-underline-face ((t (:underline t 〈comment face〉))))

antlr faces〉=
'(antlr-font-lock-keyword-face ((t (〈keyword face〉))))
'(antlr-font-lock-literal-face ((t (:foreground "〈light magenta〉"))))
'(antlr-font-lock-ruledef-face ((t (:foreground "〈dark green〉"))))
'(antlr-font-lock-ruleref-face ((t (:foreground "〈dark cyan〉"))))
'(antlr-font-lock-tokendef-face ((t (:foreground "〈medium yellow〉"))))
'(antlr-font-lock-tokenref-face ((t (:foreground "〈medium blue〉"))))

Open .jar files with archive-mode〉=
(when (boundp 'auto-coding-alist)
  (add-to-list 'auto-coding-alist '("\.[jw]ar\'" . no-conversion))
  (add-to-list 'auto-coding-alist '("\.[JW]AR\'" . no-conversion)))
(add-to-list 'auto-mode-alist '("\.[jw]ar\'" . archive-mode))
(add-to-list 'auto-mode-alist '("\.[JW]AR\'" . archive-mode))

C sharp

C sharp〉=
(add-to-list 'auto-mode-alist '("\\.cs\\'" . java-mode))
C sharp〉=
(defun tess-c-sharp-fix-tab-width ()
  (when (string-match "\\.cs\\'" (buffer-file-name))
    (setq tab-width 2)))

(add-hook 'java-mode-hook 'tess-c-sharp-fix-tab-width)

Lisp

Lisp Development〉=
(add-to-list 'auto-mode-alist '("\\.arc\\'" . lisp-mode))

Lisp Development〉=
;; completion in M-:
(when (keymapp read-expression-map)
  (define-key read-expression-map (kbd "TAB") 'lisp-complete-symbol))

Lisp Development〉=
(defun tess-comment-sexp ()
  (interactive)
  (call-interactively 'mark-sexp)
  (call-interactively 'comment-region))

(defun tess-install-lispy-bindings (map bind-ret) "FIXME" (define-key map (kbd "M-k") 'kill-sexp) (define-key map (kbd """) (seq-find 'commandp '(paredit-doublequote skeleton-pair-insert-maybe))) (define-key map (kbd "C-M-;") 'tess-comment-sexp) (when bind-ret (define-key map (kbd "RET") (seq-find 'commandp '(paredit-newline newline-and-indent)))) (define-key map (kbd "(") (seq-find 'commandp '(paredit-open-parenthesis paredit-open-list insert-parentheses))) (define-key map (kbd ")") (seq-find 'commandp '(paredit-close-parenthesis-and-newline ;; paredit-close-list-and-newline move-past-close-and-reindent))))

Lisp Development〉=
(tess-install-lispy-bindings
 (cond ((boundp 'lisp-mode-shared-map) lisp-mode-shared-map)
       ((boundp 'shared-lisp-mode-map) shared-lisp-mode-map)
       (t emacs-lisp-mode-map))
 t)

Lisp Development〉=
(eval-after-load "ielm"
  '(tess-install-lispy-bindings ielm-map nil))

Lisp Development〉=
(define-key minibuffer-local-map (kbd "M-i") (lambda () (interactive) (insert ?i)))

Lisp Development〉=
(add-to-list 'auto-mode-alist '("\.elc\'" . emacs-lisp-mode))

Lisp Development〉=
(defun tess-dedangle-parens-in-region (start end)
  "De-dangle close parens between START and END."
  (interactive "r")
  (goto-char start)
  (while (re-search-forward "[ \t\n]+)" end t)
    (replace-match ")")))

(defun tess-make-lisp-idiomatic-in-region (start end) "Make the Lisp code from START to END a bit more idiomatic. You might consider running `checkdoc' as well." (interactive "r\nP") (save-restriction (widen) (narrow-to-region start end) (setq start (point-min-marker) end (point-max-marker)) (tess-dedangle-parens-in-region start end) (indent-region start end)))

Enable paren matching〉=
(when (fboundp 'show-paren-mode)
  (show-paren-mode 1)
  (make-variable-buffer-local 'show-paren-mode))

;; to make paredit behave. (setq blink-matching-paren-on-screen nil) (setq blink-matching-delay 0.125)

;; Emacs.app (Cocoa/GNUStep port) uses mic-paren by default (when (featurep 'mic-paren) (setq paren-sexp-mode nil))

paren match face〉=
cyan bg〉 〈dark fg
paren mismatch face〉=
error face
show paren faces〉=
'(show-paren-match ((t (〈paren match face〉))))
'(show-paren-match-face ((t (〈paren match face〉))))
'(show-paren-mismatch ((t (〈paren mismatch face〉))))
'(show-paren-mismatch-face ((t (〈paren mismatch face〉))))

mic-paren faces〉=
'(paren-face-match ((t (〈paren match face〉))))
'(paren-face-mismatch ((t (〈paren mismatch face〉))))
'(paren-face-no-match ((t (〈paren mismatch face〉))))

highline faces〉=
'(highline-face ((t (〈default (alt)〉))))
'(highline-vertical-face ((t (〈default (alt)〉))))

hl-line face variables〉=
;; '(hl-line-face 'fringe)

parenface.el fetch rule〉=
parenface.el:
        curl -O http://www.davep.org/emacs/parenface.el
Lisp Development〉=
(add-hook 'after-make-frame-functions
          (lambda (frame)
            (when (display-graphic-p (tess-frame-display frame))
              (require 'parenface nil t))))

parenface faces〉=
`(paren-face ((t 〈dim this face when appropriate〉)))

Lisp Development〉=
(dolist (candidate '("mzscheme"))
  (when (executable-find candidate)
    (setq scheme-program-name candidate)))

Emacs Lisp
defun find-library〉=
(defun tess-find-user-init-file ()
  "Open my .emacs file, wherever it may be."
  (interactive)
  (find-file user-init-file))

(cond ((commandp 'find-library) (defalias 'tess-find-library 'find-library)) ((fboundp 'find-library) (defun tess-find-library (library) "Open LIBRARY." (interactive "sLibrary: ") (find-library library))) (t (defun tess-find-library (library) "Open LIBRARY." (interactive "sLibrary: ") (let ((filename (locate-library (concat library ".el")))) (if (stringp filename) (find-file filename) (message "Library %s not found." library))))))

(global-set-key (kbd "C-c L") 'tess-find-library)

abbrev-definitions〉=
(define-abbrev-table 'lisp-mode-abbrev-table '(
    ("wll" "" tess-elisp-when-locate-library-skeleton 0)
    ))

(define-abbrev-table 'emacs-lisp-mode-abbrev-table '( ("wll" "" tess-elisp-when-locate-library-skeleton 0) ))

(define-abbrev-table 'lisp-interaction-mode-abbrev-table '( ("wll" "" tess-elisp-when-locate-library-skeleton 0) ))

Lisp Development〉=
(define-skeleton tess-elisp-when-locate-library-skeleton
  "Skeleton for (when (locate-library "foo") ... ) forms."
  ;; This completing-read' form based on find-library's `interactive'
  ;; spec, but generalized to work under different Emacsen.
  (completing-read "Library name: "
                   (when (fboundp 'locate-file-completion)
                     'locate-file-completion)
                   (cons (if (boundp 'find-function-source-path)
                             find-function-source-path
                           load-path)
                         ;; (find-library-suffixes)
                         '(".el" ".el.gz" ".gz")))
  "when (locate-library "" str "")")

Lisp Development〉=
(when (locate-library "eldoc")
  (mapc (lambda (mode-hook)
          (add-hook mode-hook 'turn-on-eldoc-mode))
        '(emacs-lisp-mode-hook lisp-interaction-mode-hook
          ielm-mode-hook))

(setq eldoc-argument-case 'help-default-arg-highlight))

Lisp Development〉=
(defun tess-macroexpand-sexp-at-point ()
  "Replace the s-expresion at point with its macroexpansion."
  (interactive)

(let (pre start end) (save-excursion (up-list -1) (setq start (point)) (setq pre (sexp-at-point)) (forward-sexp 1) (setq end (point)))

(goto-char start)
(kill-region start end)

(pp (macroexpand pre) (current-buffer))))

Lisp Development〉=
(defun tess-indent-containing-sexp ()
  "Fix the indentation of the sexp containing point."
  (interactive)
  (save-excursion
    (up-list -1)
    (indent-sexp)))

(global-set-key (kbd "C-c i") 'tess-indent-containing-sexp)

Lisp Development〉=
(setq ielm-prompt "* ")

Lisp Development〉=
(add-to-list 'auto-mode-alist '("\.asd\'" . lisp-mode))

Lisp Development〉=
(add-to-list 'auto-mode-alist '("\.lisp-expr\'" . lisp-mode))

Lisp Development〉=
(mapc (lambda (hook)
        (add-hook hook
                  (lambda ()
                    (set (make-local-variable 'lisp-indent-function)
                         'common-lisp-indent-function))))
      '(lisp-mode-hook inferior-lisp-mode-hook))

Lisp Development〉=
(setq inferior-lisp-program
      (or (executable-find "sbcl")
          (executable-find "lisp")
          (executable-find "openmcl")
          (executable-find "clisp")))

Common Lisp and SLIME
.lisprc〉=
;;;; .lisprc --- Common Lisp init file.                   -*- lisp -*-

(in-package :common-lisp-user)

#-cmu (require :asdf)

#+asdf (progn #+openmcl (progn (pushnew "ccl:tools;asdf-install;" asdf:central-registry :test #'string-equal) (asdf:operate 'asdf:load-op 'asdf-install)) #+sbcl (when (asdf:find-system :sb-bsd-sockets nil) (require :asdf-install)))

Lisp Development〉=
(when (locate-library "slime")
  (autoload 'slime-mode "slime" nil t)
  (add-hook 'lisp-mode-hook (lambda nil (slime-mode 1)))
  (autoload 'inferior-slime-mode "slime" nil t)
  (add-hook 'inferior-lisp-mode-hook
            (lambda nil (inferior-slime-mode 1)))
  (add-hook 'slime-repl-mode-hook 'tess-hide-trailing-whitespace))

slime compliler faces〉=
'(slime-error-face ((t (〈error face〉))))
'(slime-warning-face ((t (〈warning face〉))))
'(slime-style-warning-face ((t (〈warning face〉))))
'(slime-note-face ((t (〈warning face〉))))
'(slime-highlight-face ((t (〈warning face〉))))

slime debugger faces〉=
'(sldb-catch-tag-face ((t (:foreground "〈medium yellow〉"))))
'(sldb-condition-face ((t (:foreground "〈light cyan〉"))))
'(sldb-detailed-frame-line-face ((t ())))
'(sldb-frame-label-face ((t (:foreground "〈dark magenta〉"))))
'(sldb-frame-line-face ((t ())))
'(sldb-local-name-face ((t (〈variable face〉))))
'(sldb-local-value-face ((t (:foreground "〈light yellow〉"))))
'(sldb-reference-face ((t (:background "cyan"))))
'(sldb-restart-type-face ((t (:foreground "〈medium magenta〉"))))
'(sldb-restart-face ((t (:foreground "〈light magenta〉"))))
'(sldb-restart-number-face ((t (:foreground "〈dark magenta〉"))))
'(sldb-section-face ((t (:foreground "〈dark yellow〉"))))
'(sldb-topline-face ((t (:foreground "〈light red〉"))))

slime repl faces〉=
'(slime-repl-prompt-face ((t (〈prompt face〉))))
'(slime-repl-output-face ((t (:foreground "〈dark magenta〉"))))
'(slime-repl-input-face ((t (:foreground "〈light magenta〉"))))
'(slime-repl-result-face ((t (:foreground "〈medium magenta〉"))))

slime inspector faces〉=
'(slime-inspector-topline-face ((t (〈default (alt)〉))))
'(slime-inspector-label-face ((t (:foreground "〈medium red〉"))))
'(slime-inspector-value-face ((t (:foreground "〈very light magenta〉"))))
'(slime-inspector-action-face ((t (:background "cyan"))))
'(slime-inspector-type-face ((t (:foreground "〈light cyan〉"))))

slime reader faces〉=
`(slime-reader-conditional-face ((t 〈dim this face when appropriate〉)))

Ruby and Rails

abbrev-definitions〉=
(define-abbrev-table 'ruby-mode-abbrev-table '(
    ("mct" "" tess-rails-migrate-create-table 0)
    ("mdt" "" tess-rails-migrate-drop-table 0)
    ("mtc" "" tess-rails-migrate-table-column 0)
    ("mac" "" tess-rails-migrate-add-column 0)
    ("mrc" "" tess-rails-migrate-remove-column 0)
    ))

ruby fetch rules〉=
rails.el:
        curl -O https://opensvn.csie.org/mvision/emacs/.emacs.d/rails.el
ruby: misc.tar.gz
        tar xzvf misc.tar.gz
        mv misc ruby
RUBY_CVSWEB="http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby"
misc.tar.gz:
        curl -o misc.tar.gz "$(RUBY_CVSWEB)/misc/misc.tar.gz?tarball=1"
ruby-mode〉=
;; Autoloads
(autoload 'ruby-mode "ruby-mode" nil t)

ruby-mode〉=
;; File associations, etc.
(add-to-list 'auto-mode-alist '("\.rb\'" . ruby-mode))
(add-to-list 'auto-mode-alist '("Rakefile\'" . ruby-mode))
;; fixme: use two-mode-mode when possible
(add-to-list 'auto-mode-alist '("\.rhtml\'" . html-mode))

ruby-mode〉=
(add-to-list 'interpreter-mode-alist '("ruby" . ruby-mode))

ruby-mode〉=
;; Key bindings
(eval-after-load "ruby-mode"
  '(define-key ruby-mode-map (kbd "RET")
     'ruby-reindent-then-newline-and-indent))

ruby-mode〉=
;; Install key bindings for running an inferior Ruby in `ruby-mode'.
(when (locate-library "inf-ruby")
  (autoload 'run-ruby "inf-ruby" nil t)
  (autoload 'inf-ruby-keys "inf-ruby" nil)
  (add-hook 'ruby-mode-hook 'inf-ruby-keys))

ruby-mode〉=
;; Skeletons

(define-skeleton tess-rails-migrate-create-table "Skeleton for creating a table in a rails migration." "Table name: "

"create_table "" str "" do |t|" \n _ \n -2 "end" \n)

(define-skeleton tess-rails-migrate-drop-table "Skeleton for dropping a table in a rails migration." "Table name: "

"drop_table "" str """ \n)

(define-skeleton tess-rails-migrate-table-column "Skeleton for adding a column in a rails migration." "Column name: "

"t.column "" str "", :" (skeleton-read "Column type: " "string"))

(define-skeleton tess-rails-migrate-add-column "Skeleton for adding a column in a rails migration." "Table name: "

"add_column "" str "", "" (skeleton-read "Column name: ") "", :" (skeleton-read "Column type: " "string"))

(define-skeleton tess-rails-migrate-remove-column "Skeleton for adding a column in a rails migration." "Table name: "

"remove_column "" str "", "" (skeleton-read "Column name: ") """)

defun tess-next-warning〉=
(defun tess-next-warning ()
  "Advance to the next buffer location in `font-lock-warning-face'."
  (interactive)
  (let ((here (point)))
    (condition-case nil
        (progn
          (goto-char (next-property-change (point)))
          (while (not (memq (get-text-property (point) 'face)
                          '(font-lock-warning-face
                            js2-error-face js2-warning-face)))
            (goto-char (next-property-change (point)))))
      (error (goto-char here)
             (error "There are no more warnings in the buffer!")))))

(global-set-key (kbd "C-c n") 'tess-next-warning)

PHP

auto-insert .php contents〉=
(define-skeleton tess-php-new-file-skeleton
  "New PHP file skeleton."
  nil
  "")

(when (fboundp 'auto-insert-mode) (add-to-list 'auto-insert-alist `(("\.php\'" . "PHP") . tess-php-new-file-skeleton)))

two-mode-mode.el fetch rule〉=
two-mode-mode.el:
        curl -O http://www.welton.it/freesoftware/files/two-mode-mode.el

Perl

cperl-mode〉=
(autoload 'cperl-mode "cperl-mode" nil t)
(add-to-list 'auto-mode-alist
             '("\\.\\([pP][Llm]\\|al\\)\\'" . cperl-mode))
(fset 'perl-mode 'cperl-mode)
(add-hook 'cperl-mode-hook 'turn-off-auto-fill)
(setq cperl-hairy t)
cperl face variables〉=
;; '(cperl-pod-face 'font-lock-doc-string-face)
'(cperl-pod-head-face 'font-lock-variable-name-face)
;; '(cperl-here-face 'font-lock-doc-string-face)
'(cperl-invalid-face 'font-lock-warning-face)

cperl faces〉=
'(cperl-array-face ((t (:foreground "〈light magenta〉"))))
'(cperl-array ((t (:foreground "〈light magenta〉"))))
'(cperl-nonoverridable-face ((t (:foreground "〈dark yellow〉"))))
'(cperl-nonoverridable ((t (:foreground "〈dark yellow〉"))))
'(cperl-hash-face ((t (:foreground "〈medium magenta〉"))))
'(cperl-hash ((t (:foreground "〈medium magenta〉"))))

Python, Pymacs, Rope, and Ropemacs

Setting PATH in Zsh〉=
for python in 'python' 'python2' 'python3'; do
    if command-recognized $python; then
        add-to-path `$python -m site | grep USER_BASE | cut -d \' -f 2`/bin
    fi
done

Setting PATH in PowerShell〉=
if (Get-Command python3 2> $null) {
    $python_sitedir=((python3 -m site | Select-String "^USER_BASE: '(.)'").Matches.Groups[1].Value)
    Join-Paths $python_sitedir '' 'Scripts' | Add-PathsToEnvPATH
    Remove-Variable 'python_sitedir'
}
Pymacs and Ropemacs〉=
(when (locate-library "pymacs")
  (autoload 'pymacs-load "pymacs")
  〈Ropemacs〉)

Ropemacs〉=
(defun tess-load-ropemacs ()
  "Load ropemacs iff pymacs is installed and ropemacs isn't loaded."
  (interactive)
  (when (fboundp 'pymacs-load)
    (unless (featurep 'ropemacs)
      (pymacs-load "ropemacs" "rope-" t)
      (ropemacs-mode 1))))

(add-hook 'python-mode-hook 'tess-load-ropemacs)

python template〉=
(let ((py-template "template.py"))
  (when (file-exists-p (expand-file-name py-template
                                         auto-insert-directory))
    (add-to-list 'auto-insert-alist
                 `(("\.py\'" . "Python") . ,py-template))))

insert/template.py〉=
#!/usr/bin/env python3

if name == 'main': pass

parse-sexp-ignore-comments〉=
;; http://article.gmane.org/gmane.emacs.devel/64807
(setq parse-sexp-ignore-comments t)

Choose which python mode to use〉=
(unless (locate-library "python")
  (when (locate-library "python-mode")
    (autoload 'python-mode "python-mode" nil t)
    (add-to-list 'auto-mode-alist
                 '("\.\(py\|tac\)\'" . python-mode))
    (add-to-list 'interpreter-mode-alist
                 '("python" . python-mode))))

Golang

Setting PATH in Zsh〉=
add-to-path ~/go/bin
#### Rust
configure rust environment〉=
export RUSTUP_HOME=~/${SYSNAME}
export CARGO_HOME=~/${SYSNAME}

Swift

swift major mode fetch rules〉=
swift-mode.el:
        curl -O https://raw.githubusercontent.com/apple/swift/master/utils/swift-mode.el
swift-project-settings.el:
        curl -O https://raw.githubusercontent.com/apple/swift/master/utils/swift-project-settings.el

Setting PATH in Zsh〉=
add-to-path /usr/share/swift/usr/bin
Swift〉=
(when (executable-find "xcode-select")
  (let* ((xcode-dir
          (with-temp-buffer
            (call-process "xcode-select" nil t nil "-p")
            (buffer-substring (point-min) (1- (point-max)))))
         (xcode-site-lisp
          (format "%s/Toolchains/XcodeDefault.xctoolchain/%s/"
                  xcode-dir
                  "usr/share/emacs/site-lisp")))
    (add-to-list 'load-path xcode-site-lisp)))

(when (locate-library "swift-mode") (autoload 'swift-mode "swift-mode") (add-to-list 'auto-mode-alist '("\.swift\'" . swift-mode)))

(when (locate-library "lsp") (add-hook 'swift-mode-hook 'lsp) (let ((sourcekit-lsp (executable-find "sourcekit-lsp"))) (when (and (locate-library "lsp-sourcekit") sourcekit-lsp) (require 'lsp-sourcekit) (setq lsp-sourcekit-executable sourcekit-lsp))))

Haskell

haskell-mode fetch fules〉=
haskell-mode-1.45/haskell-mode.el: haskell-mode-1.45.tar.gz
        tar xzvf haskell-mode-1.45.tar.gz
haskell-mode-1.45.tar.gz:
        curl -O http://www.haskell.org/haskell-mode/haskell-mode-1.45.tar.gz
haskell-mode〉=
(add-to-list 'auto-mode-alist '("\\.\\([hg]s\\|hi\\)\\'" . haskell-mode))
(add-to-list 'auto-mode-alist '("\\.l[hg]s\\'" . literate-haskell-mode))

(autoload 'haskell-mode "haskell-mode" nil t) (autoload 'literate-haskell-mode "haskell-mode" nil t)

(mapc (lambda (hook) (add-hook 'haskell-mode-hook hook)) '(turn-on-haskell-font-lock turn-on-haskell-decl-scan turn-on-haskell-doc-mode turn-on-haskell-indent turn-on-haskell-hugs))

Structure of some very large config files

.emacs

.emacs〉=
;;; .emacs --- Theresa O'Connor's Emacs configuration -*- emacs-lisp -*-

Elisp Copyright Statement

;;; Code:

(require 'cl-lib) (require 'seq) (unless (require 'xdg nil t) (defun xdg-config-home (&rest ignore) (expand-file-name ".config" "~")))

Custom hooks〉 〈Configure max-lisp-eval-depth and max-specpdl-size〉 〈Garbage collect when tabbing away from Emacs〉 〈basic w32 fixups〉 〈define data-vol and shared-home for emacs

define tess-elisp-dirs and tess-elisp-dir〉 〈define tess-code-dir

defun tess-run-executable〉 〈Set exec-path from path_helper on macOS〉 〈Configure SYSNAME in Emacs〉 〈Ensure HOME/bin is in exec-path〉 〈Add SYSNAME/bin to exec-path〉 〈Config data-vol and shared-home (Emacs)〉 〈Fix exec-path under Emacs

;;; Compatibility, part 2. Checking for the availability of various ;;; functions which I'll be using later on.

;; Not defined in Emacs. (if (fboundp 'variable-obsolete-p) (defalias 'tess-variable-obsolete-p 'variable-obsolete-p) 〈defsubst tess-variable-obsolete-p〉)

;; Not defined in older Emacsen. (unless (fboundp 'custom-autoload) 〈defun custom-autoload〉)

(cond ((fboundp 'set-frame-parameter) (defalias 'tess-set-frame-parameter 'set-frame-parameter)) ((fboundp 'set-frame-property) (defalias 'tess-set-frame-parameter 'set-frame-property)))

;; Defined in multi-tty Emacs (if (fboundp 'window-system) (defalias 'tess-window-system 'window-system) (defun tess-window-system (&optional frame) window-system))

(cond ((fboundp 'frame-display) ;; Multi-TTY Emacs (defalias 'tess-frame-display 'frame-display)) (t (defalias 'tess-frame-display 'ignore)))

Set LANG (Emacs)

;;; Utilities.

defsubst tess-alist〉 〈defun tess-add-to-list*

;;; Frob the Emacs command line.

defvar tess-server-emacs〉 〈enable -gnus

;;; Frobbing `load-path' and checking for any third-party elisp files on ;;; this machine.

Configure load-path〉 〈put gist.el and dependencies in load-path〉 〈Configure Info-default-directory-list〉 〈Ensure we load the right Gnus

(when (locate-library "package") 〈Configuring package.el〉)

;;; Define various constants and predicates that will be used throughout ;;; this .emacs file to conditionalize code. For instance, I define ;;; `tess-tty-p' so that I can specify particular Emacs configuration ;;; bits for TTYs only.

Define display type predicates

;;; Work-arounds for things I find annoying in their default state, and ;;; basic customizations.

case-insensitive filename completion〉 〈Stop Cocoa Emacs from using the system highlight〉 〈Ensure after-make-frame-functions get run for first frame〉 〈Disable the Emacs splash screen〉 〈setq cd-path〉 (when (eq system-type 'windows-nt) 〈Fix exec-path under Windows〉) 〈Key binding for goto-line〉 〈require-final-newline〉 〈inhibit default init〉 〈change-log-default-name〉 (when (featurep 'aquamacs) 〈Disable CUA-mode〉) 〈transient mark mode〉 〈Enable disabled commands〉 〈disable overwrite-mode〉 〈Enable recursive minibuffers〉 〈sentence-end-double-space〉 〈defalias yes-or-no-p〉 〈indent-tabs-mode〉 〈truncate-lines〉 〈Disable blinking cursors〉 〈Fix scrolling〉 〈multi-region〉 〈Minibuffer Electric Default Mode〉 〈Fix size of temporary buffer windows〉 〈Enable minibuffer resizing〉 〈uniquify〉 〈Line and Column numbering〉 〈Don't echo passwords in comint mode〉 〈Poor-man's diminish.el〉 〈Define utilities for locating and running Mac apps〉 〈Ensure XCode Command Line Tools are in exec-path〉 〈Fix Emacs behavior when in the macOS dock〉 〈LC COLLATE (Emacs)〉 〈comment-style〉 〈auto-mode-case-fold〉 〈defun tess-insert-local-variables-spec〉 〈Apropos do all〉 〈Disable pager when git is run from Emacs

;; completion

setq completion-ignore-case〉 〈Disable SPC minibuffer completion〉 (when (locate-library "pcomplete") 〈pcomplete〉)

(cond ((locate-library "longlines") 〈longlines〉) ((fboundp 'visual-line-mode) 〈alias longlines with visual-line-mode〉))

isearch highlight current match〉 〈Enable abbrevs〉 〈Enable paren matching〉 〈Basic auto-fill configuration〉 〈fill-column〉 〈Highlight Trailing Whitespace〉 〈user-mail-address〉 〈Increase logging amount〉 〈defun tess-clear〉 〈defun tess-ip〉 〈timestamp〉 〈goto-address〉 〈indicate-empty-lines〉 〈Configure auto-insert-mode〉 〈defun kr-major-mode-p〉 〈defun tess-read-major-mode〉 〈edit region in a different major mode〉 〈defun tess-kill-mode-buffers〉 〈defun help-default-arg-highlight〉 〈tess-find-mode〉 〈defun tess-wash-smart-quotes〉 〈linum〉 〈archive-mode〉 〈configure woman〉 〈Emoji utilities

;; Customizations which we only want to happen when we're using ;; Emacs on a TTY. (add-hook 'after-make-frame-functions (lambda (frame) (when (tess-tty-p (tess-frame-display frame)) 〈TTY terminal-coding-system〉 〈Handle my FreeBSD keymap (Emacs)〉 〈TTY web browser default〉)))

;;; Various buffer-switching enhancements.

Organize buffer menu by major mode〉 〈Better buffer switching〉 〈ibuffer-fontification-alist

;;; gnuclient / emacsclient / remote editing

emacs server〉 〈TRAMP: Transparent Remote Access over Multiple Protocols

;;; Key bindings.

Restore center-line keybinding〉 〈alternate set-mark-command keybinding〉 〈multi-tty C-x C-c hack〉 (add-hook 'after-make-frame-functions (lambda (frame) (when (eq (window-system frame) 'w32) 〈Windows modifier key bindings〉) (when (eq (window-system frame) 'ns) 〈Mac modifier key bindings〉)))

Key binding for bury-buffer〉 〈Bindings for the scroll wheel in the mode line〉 〈Key binding for list-text-properties-at〉 〈find-function key bindings〉 〈bind ucs-insert to C-c u〉 〈Sun Type 6 USB keyboard key bindings〉 〈Sun keyboard key bindings〉 〈Fix insertchar key binding〉 〈Key binding for FFAP〉 〈Fix common Emacs typos〉 〈additional rectangle command bindings〉 〈Macro DWIM stuff〉 〈Duplicate some meta keys on super〉 〈smerge-mode

;;; Major Emacs-based applications, and Emacs interfaces to other major ;;; applications.

ledger-mode〉 〈EMMS〉 ;; Emacs games 〈Emacs Games

;; Viper, the VI-like editor in Emacs

Enable Viper in .emacs〉 〈Configure Viper's toggle key〉 〈Ensure Viper doesn't mess with my cursor type〉 (when (and (boundp 'viper-mode) viper-mode (featurep 'aquamacs)) 〈Fix Viper under Aquamacs〉)

Use SSH for M-x rsh, and make M-x ssh

;; Eshell, the Emacs Shell (when (locate-library "eshell") 〈The Emacs Shell〉 〈Eshell prompt〉 〈Use ANSI escape sequences in Eshell〉 〈fix s-p in eshell

Various custom Eshell commands〉 (eval-after-load "em-ls" '(progn 〈Augment eshell's ls to allow middle-clicking on files〉)))

;; Emacs web browsing, web searching, and more! 〈disable use of ? as completion help in minibuffer〉 (when (locate-library "w3m") 〈emacs-w3m〉 〈defun tess-w3m-edit-emacswiki-page〉 (eval-after-load "w3m" '(progn 〈lj: URLs in emacs-w3m〉 〈editing emacswiki pages with w3m〉)))

Using Backpack from within Emacs〉 〈Using Twitter from within Emacs〉 〈Using Google〉 〈ELL〉 〈wikiarea〉 〈EmacsWiki〉 〈wikipedia major mode〉 〈mediawiki major mode

;; Email. 〈sieve〉 〈mail-user-agent〉 〈Basic email look and feel〉 〈Edit Gnus score files as Gnus score files〉 〈boxquote〉 〈The Insidious Big-Brother Database〉 〈EUDC

;; Dired, the Emacs directory editor.

Dired, the Directory Editor

;; ljupdate, an Emacs LiveJournal client 〈ljupdate, an Emacs LiveJournal client

;; Disable trying gnutls when it's not available (when (and (not (gnutls-available-p)) (require 'tls nil t)) (unless (executable-find "gnutls-cli") (setq tls-program (seq-filter (lambda (candidate) (string-match "gnutls-cli" candidate)) tls-program))))

;; ERC, an Emacs IRC client (when (locate-library "erc") 〈ERC, an Emacs IRC Client〉)

;; rcirc (when (locate-library "rcirc") 〈rcirc〉)

(when (locate-library "csv") 〈CSV〉)

;;; Programming and other forms of document preparation.

Configure powershell-mode in Emacs

(when (locate-library "editorconfig") 〈editorconfig〉)

ninja-mode

parse-sexp-ignore-comments〉 〈Programming Utilities〉 〈defun tess-next-warning〉 〈Make paired characters electric〉 〈Configuring glasses-mode

Swift

(when (locate-library "gitsum") 〈gitsum〉)

(when (locate-library "gist") 〈gist〉)

(when (locate-library "psvn") 〈psvn〉)

(when (locate-library "vc-svn") 〈vc-svn〉)

C sharp〉 〈CamelCase-aware killing functions〉 〈Open .jar files with archive-mode

(when (locate-library "haskell-mode") 〈haskell-mode〉)

;; Moved load of generic-x up before we look for javascript.el: both put ;; entries in `auto-mode-alist' for "\.js\'", and I want the entry ;; from javascript.el. 〈generic-x

XDG desktop files alternate extension

Web Development

(when (locate-library "markdown-mode") (autoload 'markdown-mode "markdown-mode" nil t) 〈Editing Markdown files〉)

(when (locate-library "quickurl") 〈Use quickurl to expand links in Markdown and HTML〉)

(when (locate-library "shr") 〈shr config〉)

(when (locate-library "bikeshed") (autoload 'bikeshed-mode "bikeshed" nil t) 〈Editing Bikeshed files〉)

(when (locate-library "deft") (autoload 'deft "deft" nil t) 〈Deft〉)

Lisp Development〉 〈defun find-library〉 (when (locate-library "dns-mode") 〈DNS mode〉) 〈Open RPM spec files in rpm-spec-mode〉 〈rfcview〉 〈cfengine

(when (locate-library "ruby-mode") 〈ruby-mode〉)

(when (locate-library "cperl-mode") 〈cperl-mode〉)

;;; Python

Pymacs and Ropemacs〉 〈Choose which python mode to use

Open PostgreSQL views and source files in sql-mode〉 〈Mathematics〉 〈AUCTeX〉 〈disable TeX {sub,super}script frobbing〉 〈table〉 〈ensure org-mode is autoloaded〉 (when (fboundp 'org-mode) 〈org-mode〉)

noweb

;;; Work.

Integer thing at point

Bug tracker links

;;; Customizations which are specific to using Emacs under the various ;;; windowing systems.

Choose the right browser

Windowing〉 〈Disable one-buffer-one-frame-mode〉 (when (featurep 'aquamacs) 〈Disable Aquamacs' various bells and whistles〉) 〈Disable smart-frame-positioning-mode

;;; Customizing Emacs' colors.

256 colors (Emacs)〉 〈Arrow keys in local screen instances

face-list〉 (when (display-color-p) 〈htmlize〉 〈tess-htmlize〉 (cond 〈custom-theme〉 〈color-theme〉) 〈term faces〉 〈Enable Font Locking〉 〈ANSI color sequences〉)

;;; Host-specific customizations.

Host-specific customizations

;;; .emacs ends here

.gnus

.gnus〉=
;;; .gnus --- Theresa O'Connor's Gnus configuration -*- emacs-lisp -*-

Elisp Copyright Statement

;;; Code:

(setq gnus-agent nil)

(add-hook 'gnus-load-hook (lambda () 〈Gnus config that should only run once〉))

Gnus config that should run each time Gnus is started

;; Local configuration

Local Gnus configuration

;;; .gnus ends here

Gnus config that should only run once〉=
Gnus config that should run each time Gnus is started〉=
Gnus Authentication Sources〉
〈I am not a Gnus novice any more〉
〈Article headers〉
〈tess-insert-citation-line〉
〈Choosing which citation code to use〉
〈Configure gnus-face-N〉
〈Gnus Group buffer looks〉
〈Gnus Summary buffer looks〉
〈override gnus-goto-colon〉
〈gnus-ignored-from-addresses〉
〈defun tess-follow-link-at-point〉
〈use message-forward-subject-fwd if available〉
〈configure gnus verbosity〉
〈mimedown command〉
〈misc gnus settings〉
〈Use open to preview PDFs on macOS〉
〈Disable displaying SVG in HTML emails〉
〈scoring in gnus〉
〈enable gnus topic mode〉
〈gnus topic mode keybindings〉
〈nnfolder configuration〉
〈nnmail configuration〉
〈fix dumb quotes in Gnus〉
〈gnus topic configuration〉
〈gnus subscribe randomly〉
〈tess typo gnus key bindings〉
〈key binding for gnus-group-mail〉
〈disable killing of groups by mistake〉
〈disable indenting of topics by mistake〉
〈Strong Bad email deletion〉
〈defun tess-gnus-mark-thread-advance〉
〈GCC header handling〉
〈SMTP handling〉
〈Gnus select methods〉
〈spam reporting〉
〈Gnus posting styles〉
〈Emoji in Gnus

;; Mailing lists, at the W3C and elsewhere

handle mailing lists nicely

Gmane special-handling

Cleaning up mailing list email

Reading W3C and WHATWG mailing list archives in Gnus

Generating this HTML file from source

Noweb

I use noweb to generate all of my dotfiles from this source file.

I edit the single source file using noweb-mode in Emacs.

Setting PATH in Zsh〉=
add-to-path /usr/local/noweb

noweb〉=
(when (locate-library "noweb-mode")
  (autoload 'noweb-mode "noweb-mode" nil t)
  (add-to-list 'auto-mode-alist '("\.nw\'" . noweb-mode))
  (setq noweb-mode-prefix (kbd ""))

always use visual-line-mode in noweb〉 〈fix noweb redisplay〉 〈fix M-q in noweb〉 〈fix highlighting in noweb elisp〉 〈fix noweb-default-code-mode〉)

always use visual-line-mode in noweb〉=
(add-hook 'noweb-select-mode-hook
            (lambda () (visual-line-mode 1)))

fix highlighting in noweb elisp〉=
(when (fboundp 'font-lock-add-keywords)
  (add-hook 'emacs-lisp-mode-hook
            (lambda ()
              (when (and (boundp 'noweb-mode) noweb-mode)
                (font-lock-add-keywords
                 nil
                 '(("\([<][<][^>]*[>][>]\)"
                    (1 font-lock-string-face))))))))

fix noweb redisplay〉=
(defadvice noweb-update-chunk-vector (around tess-noweb-redisplay
                                             activate)
  (let ((inhibit-redisplay t)
        (tess-noweb-redisplay-message
         "Updating noweb's chunk vector"))
    (message "%s..." tess-noweb-redisplay-message)
    ad-do-it
    (message "%s...done" tess-noweb-redisplay-message)))

fix noweb-default-code-mode〉=
(setq-default noweb-default-code-mode 'emacs-lisp-mode
              noweb-code-mode         'emacs-lisp-mode)
fix M-q in noweb〉=
(eval-after-load "noweb-mode"
  '(fset 'noweb-fill-paragraph-chunk 'fill-paragraph))

Extracting dotfiles

.hushlogin〉=
Makefile〉=
DOTFILES=.bashrc .emacs .ercrc.el .exrc .freebsd-keymap fortune \
         .gitconfig .gnus .hushlogin .lisprc .nethackrc .quickurls \
         .screenrc .viper .zshenv .zprofile .zshrc .zlogin

SCRIPTS=bin/nw-to-md bin/mimedown bin/recvcfg

TEMPLATES=insert/template.atom insert/template.css
insert/template.html insert/template.js
insert/template.py insert/template.tex
insert/template.zsh insert/.fs-literal

ELISP=elisp/hober2-theme.el elisp/Makefile elisp/subdirs.el

ZSH_FUNDIR=.local/share/zsh/functions ZSH_FUNCS=$(ZSH_FUNDIR)/fortune

PWSH_MODDIR=.local/share/powershell/Modules PWSH_MODULES=$(PWSH_MODDIR)/Update-HoberCfg/Update-HoberCfg.psm1
$(PWSH_MODDIR)/Get-ChildItemName/Get-ChildItemName.psm1

LISPCONFIG=.sbclrc init.lisp openmcl-init.lisp

SSHAUTHKEYS=.ssh/authorized_keys .ssh/authorized_keys2 SSHCONFIG=.ssh/config

SVNCONFIG=.subversion/config

W3MCONFIG=.w3m/config

DIRS=$(PWSH_MODDIR) $(ZSH_FUNDIR) .ssh .subversion .w3m bin code elisp
local insert .config/powershell

we don't extract these by default.

OTHER=abbrev-definitions freeciv.serv

SOURCE=hobercfg.nw

HOBERCFG=$(DOTFILES) $(SCRIPTS) $(TEMPLATES) $(ELISP)
$(SSHCONFIG) $(SSHAUTHKEYS) $(SVNCONFIG)
$(W3MCONFIG) $(ZSH_FUNCS) .abbrev_defs code/Makefile
$(PWSH_MODULES) .config/powershell/profile.ps1

Makefile〉=
dist tarball trarball: hobercfg.tar.gz

usage: @echo "USAGE: gmake [config|html|tarball|clean|]"

html: index.html

index.html: hobercfg.html cp hobercfg.html index.html

Makefile〉=
Library/Preferences/Emacs.plist:
        notangle -t8 -REmacs.plist $(SOURCE) > $@

Makefile〉=
code/Makefile: code $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
wc:
        wc -l $(DOTFILES) $(SCRIPTS) $(TEMPLATES) $(ELISP)
        wc -l $(SOURCE)

Makefile〉=
extract: hobercfg.tar
        tar xvf hobercfg.tar
hobercfg.tar: hobercfg.tar.gz
        gzip -d hobercfg.tar.gz

Makefile〉=
config: Makefile $(HOBERCFG)

Makefile〉=
clean:
        rm -f hobercfg.aux hobercfg.core hobercfg.ilg hobercfg.ind 
hobercfg.idx hobercfg.log hobercfg.out hobercfg.toc
hobercfg.md hobercfg.nw~

Makefile〉=
distclean: clean
        rm -f $(DOTFILES) $(SCRIPTS) $(TEMPLATES)
        rmdir bin insert

Makefile〉=
copy: $(DOTFILES)
        cp $(DOTFILES) "$(TODIR)"

Makefile〉=
hobercfg.tar.gz: $(HOBERCFG)
        tar czvf $@ $(HOBERCFG)

Makefile〉=
.abbrev_defs: abbrev-definitions
        mv abbrev-definitions $@

Makefile〉=
.config/powershell/profile.ps1: $(SOURCE) .config/powershell
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile $(DOTFILES) $(OTHER): $(SOURCE) notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
$(DIRS):
        mkdir -p $@

Makefile〉=
$(SCRIPTS): bin $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@
        chmod +x $@

Makefile〉=
$(TEMPLATES): insert $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
$(ELISP): elisp $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
$(ZSH_FUNCS): .local/share/zsh/functions $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
$(PWSH_MODULES): .local/share/powershell/Modules/Update-HoberCfg .local/share/powershell/Modules/Get-ChildItemName $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@
.local/share/powershell/Modules/Update-HoberCfg:
        mkdir -p .local/share/powershell/Modules/Update-HoberCfg
.local/share/powershell/Modules/Get-ChildItemName:
        mkdir -p .local/share/powershell/Modules/Get-ChildItemName

Makefile〉=
$(SSHAUTHKEYS): .ssh $(SOURCE)
        notangle -t8 -R.ssh/public-keys $(SOURCE) > $@
$(SSHCONFIG): .ssh $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@
        chmod 700 .ssh

Makefile〉=
$(SVNCONFIG): .subversion $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
$(W3MCONFIG): .w3m $(SOURCE)
        notangle -t8 -R$@ $(SOURCE) > $@

Makefile〉=
$(LISPCONFIG): .lisprc $(SOURCE)
        ln -s .lisprc $@

Makefile〉=
%.md: %.nw
        noweave -n -backend bin/nw-to-md $< > $@
%.html: %.md
        notangle -t8 -Rpreamble $(SOURCE) > $@
        doctoc --maxlevel 6 $<
        marked --gfm --smart-lists -i $< >> $@
        notangle -t8 -Rpostamble $(SOURCE) >> $@

Makefile〉=
.SUFFIXES : .nw .html .md

Distributing my dotfiles to different machines

bin/recvcfg〉=
#!/usr/bin/env zsh

host=${1:-mallow} tarball=hobercfg.tar.gz

if whence rsync > /dev/null; then command=rsync flags=-LPv elif whence scp > /dev/null; then command=scp flags= else print 'Neither rsync nor scp are available!' >& 2 exit 1 fi

cd $command $flags $host:$tarball $tarball && tar xPzvf $tarball

.local/share/powershell/Modules/Update-HoberCfg/Update-HoberCfg.psm1〉=
[CmdletBinding(PositionalBinding=$false)]
param(
    [string]$RemoteHost='mallow.cfhp.org',
    [string]$RemoteUser='tess',
    [string]$Path='hobercfg.tar.gz',
    [string]$Destination=$Home
)

function Update-HoberCfg { try { pushd $Destination

Write-Information "Copying ${Path} from ${RemoteHost} as ${RemoteUser}..." -InformationAction Continue
scp ${RemoteUser}@${RemoteHost}:${Path} .
if (-not $?) {
    throw "Unable to fetch ${Path}!"
}

Write-Information "Extracting ${Path}..." -InformationAction Continue
tar xPzf ${Path}
if (-not $?) {
    throw "Unable to untar ${Path}!"
}

if ([Environment]::OSVersion.Platform -eq 'Unix') {
    Write-Information 'Emacs config is already in the right place.' -InformationAction Continue
} else {
    $emacs_d = "${Destination}\AppData\Roaming\.emacs.d"
    if (-not (Test-Path -Path $emacs_d -PathType Container)) {
        New-Item -Path $emacs_d -Type Directory -Force
    }

    if (Test-Path -Path .emacs) {
        Write-Information 'Updating .emacs...' -InformationAction Continue
        Move-Item -Path .emacs -Destination $emacs_d\init.el -Force
    }
}

$myprofile = "$Home\.config\powershell\profile.ps1"
if ((Test-Path $myprofile) -and
    ($profile.CurrentUserAllHosts -ne (Resolve-Path $myprofile))) {

    Write-Information 'Updating PowerShell profile...' -InformationAction Continue
    New-Item -Path $profile.CurrentUserAllHosts -Type File -Force | out-null
    Move-Item -Path $myprofile -Destination $Profile.CurrentUserAllHosts -Force

    # If we needed to move the profile, we'll need to move each module too.

    $xdgmodules = "$Home\.local\share\powershell\Modules"
    $winmodules = Join-Path (Get-ChildItem $Profile.CurrentUserAllHosts).Directory 'Modules'

    foreach ($module in Get-ChildItem $xdgmodules) {
        Write-Host ("Updating {0} module.." -f $module.Name) -NoNewLine
        $targetdir = Join-Path $winmodules $module.Name
        New-Item -Path $targetdir -Type Directory -Force | Out-Null
        foreach ($file in Get-ChildItem $module) {
            Write-Host '.' -NoNewLine
            Move-Item $file $targetdir -Force
        }
        Write-Host ''
    }
} else {
    Write-Information 'PowerShell config is already in the right place.' -InformationAction Continue
}

popd

} catch { Write-Error $_ } }

Export-ModuleMember -Function Update-HoberCfg

recvcfg alias (PowerShell)〉=
Set-Alias -Name recvcfg -Value Update-HoberCfg

Custom markdown backend for Noweb

bin/nw-to-md〉=
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re, string, sys

from enum import Enum

class Mode(Enum): META = 1 CODE = 2 DOCS = 3

class ToMarkdown: def init(self): self.mode = Mode.META self.suppress_next_nl = False self.chunk_number = -1 self.named_chunks = set()

def id_for(self, chunk):
    drop_punct = str.maketrans(' ','-', string.punctuation)
    return chunk.lower().translate(drop_punct)

def run(self, infile=sys.stdin, outfile=sys.stdout):
    [self.process_line(line, outfile) for line in infile]

def process_line(self, line, outfile):
    line = line[0:-1]

    if line.startswith("@file"):
        pass
    elif line.startswith("@begin"):
        bits = line.split()
        if bits[1] == 'code':
            self.mode = Mode.CODE
        if bits[1] == 'docs':
            self.mode = Mode.DOCS
        self.chunk_number = int(bits[2])
    elif line.startswith("@end "):
        if self.mode == Mode.CODE:
            print("</code></pre></figure>", file=outfile, end='')
        self.mode = Mode.META
    elif line.startswith("@text"):
        print(line[6:], file=outfile, end='')
    elif line.startswith("@nl"):
        if not self.suppress_next_nl:
            print('', file=outfile)
        self.suppress_next_nl = False
    elif line.startswith("@defn"):
        chunk_name = line[6:]
        chunk_id = self.id_for(chunk_name)

        if chunk_name not in self.named_chunks:
            self.named_chunks.add(chunk_name)
        else:
            chunk_id = chunk_id + "-%d" % self.chunk_number

        print("<figure id='%s'><figcaption>〈<a href='#%s'>%s</a>〉=</figcaption><pre><code>"
              % (chunk_id, chunk_id, chunk_name), file=outfile, end='')
        self.suppress_next_nl = True
    elif line.startswith("@use"):
        chunk_name = line[5:]
        print("〈<a href='#%s'>%s</a>〉" % (self.id_for(chunk_name), chunk_name), file=outfile, end='')
    elif line.startswith("@quote"):
        print('`', file=outfile, end='')
    elif line.startswith("@endquote"):
        print('`', file=outfile, end='')
    # Tagging keywords
    elif line.startswith("@line"):
        pass
    elif line.startswith("@language"):
        pass
    elif line.startswith("@index"):
        pass
    elif line.startswith("@xref"):
        pass
    # Wrapper keywords
    elif line.startswith("@header"):
        pass
    elif line.startswith("@trailer"):
        pass
    # Error keyword
    elif line.startswith("@fatal"):
        pass
    # Lying, cheating, stealing keyword
    elif line.startswith("@literal"):
        pass

if name == "main": ToMarkdown().run()

Markdown to HTML

preamble〉=








postamble〉=

Back matter

Emacs local variables for hobercfg.nw