Startup

Initial set-up

We are bootstrapping to some new server and want to stay as self-contained in the .emacs.d directory as possible.

;; we want to replace all calls to `user-emacs-directory' with `initel-directory'
(setq initel-directory (file-name-directory (or load-file-name buffer-file-name)))

I carry around two laptops: My main machine runs Linux and my secondary machine runs Windows. I need some mechanism to distinguish between the two platforms

(defconst on-windows (string-equal system-type "windows-nt"))

I pull packages from a server under my control which mirrors the ELPA/MELPA/whatever packages I use in my config. To keep others from accessing it, we keep access password protected. To download from a password-protected ELPA archive, we need to add the username and password to the URL. This looks like the following. This is not the username, password, or server that is actually used.

(setq package-archive-url "https://username:[email protected]/elpa")

Set up `package.el' to pull from my server.

(setq package-user-dir (concat initel-directory "elpa"))
;; https://lists.gnu.org/archive/html/help-gnu-emacs/2019-08/msg00106.html
(unless on-windows
  (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
(require 'package)
(setq package-archives `(("dennis" . ,package-archive-url)))
(package-initialize)

Layers and themes

;; We enable or disable one of or several "layers", similar to how spacemacs
;; handles its configuration. Defaults to
(defvar do.layers/enabled-layers
  '(minimal faces org lsp terminal snippets mode-line completion
    cpp latex octave scheme julia python matlab misc mail)
  "A list of the enabled Layers for this configuration.

Currently available layers:

- minimal: The minimum viable configuration
- faces: A few tricks with faces, mainly for graphical Emacs
- org: `org-mode' customizations
- terminal: settings for the terminal environment (`ansi-term')
- snippets: `yasnippet' configuration
- completion: `company-mode' configuration
- mode-line: Custom mode-line
- mail: E-Mail configuration

- octave: GNU Octave settings
- cpp: C and C++ programming environment
- matlab: MATLAB programming environment
- julia: Julia programming environment
- python: Python programming environment
- scheme: Scheme programming environment
- latex: All things LaTeX (using AUCTeX)
- misc: Miscellaneous programming and text environments")

;; We enable one of our themes using this variable
(defvar do.theme/enabled-theme
  'dark
  "The choice of theme. The choices are:

- dark: Based on the internal `wombat-theme'
- light: Based on john2x's plan9-theme
- nil: No theme customizations at all")

Site File

;; We can customize the startup for a different machine by incluing elisp in
;; the special file "~/.emacs-site.el". This is loaded before any packages are
;; loaded and any variables set here might be overwritten. However, this can be
;; used to specify different themes or different layers for different machines,
;; for example.
(let ((site-file "~/.emacs-site.el"))
  (when (file-exists-p site-file)
    (load site-file)))
;; TODO make nicer
(let ((site-file "~/.emacs-site/emacs-site.el"))
  (when (file-exists-p site-file)
    (load site-file)))

use-package

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(setq use-package-verbose t)
(eval-when-compile
  (require 'use-package))
(use-package bind-key :ensure t :demand)
(use-package diminish :ensure t :demand)
(use-package dash
  :ensure t
  :demand
  :config
  (dash-enable-font-lock))
(use-package let-alist
  :ensure t
  :demand)

Exec path and other stuff

;; exec path
(unless on-windows
  (use-package exec-path-from-shell
    :ensure t
    :init
    (when (display-graphic-p)
      (exec-path-from-shell-initialize))))

;; Moved the custom.el stuff into its own file called ~/.emacs.d/customize.el
(setq custom-file (concat initel-directory "customize.el"))
(load custom-file)

;; Normally, I could use the =system-name= variable to get the current
;; hostname, but it seems to return the value of =hostname -f=, which is not
;; what I want. Therefore, I find the hostname manually by calling
;; =shell-command-to-string= and stripping some whitespace. This will probably
;; /not/ work on windows.
(let ((hn-executable "hostname"))
  (when (executable-find hn-executable)
    (setq hostname (->> hn-executable
      (shell-command-to-string)
      (replace-regexp-in-string "[ \t\n]*\\'" "")
      (replace-regexp-in-string "\\`[ \t\n]*" "")))))

;; ansi-term directory tracking breaks when "system-name" evaluates to
;; "<hostname>.Home". This is a dirty fix, but it works for now. Maybe
;; I can investigate further into this one day.
(setq system-name hostname)

Now we are ready to load the rest of the config.