7a3d95d70b
Which fixes a bug when running on Linux, that doesn't need the Shell PATH set (at least, not for me).
227 lines
8.8 KiB
Org Mode
227 lines
8.8 KiB
Org Mode
#+TITLE: My Emacs Bootstrap
|
|
#+AUTHOR: Howard X. Abrams
|
|
#+DATE: 2021-10-08
|
|
#+FILETAGS: :emacs:
|
|
|
|
A literate programming file for bootstraping my Emacs Configuration.
|
|
|
|
#+BEGIN_SRC emacs-lisp :exports none
|
|
;;; bootstrap.el --- file for bootstraping my Emacs Configuration
|
|
;;
|
|
;; Copyright (C) 2021 Howard X. Abrams
|
|
;;
|
|
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams>
|
|
;; Maintainer: Howard X. Abrams
|
|
;; Created: October 8, 2021
|
|
;;
|
|
;; This file is not part of GNU Emacs.
|
|
;;
|
|
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
|
|
;; ~/other/hamacs/bootstrap.org
|
|
;; And tangle the file to recreate this one.
|
|
;;
|
|
;;; Code:
|
|
#+END_SRC
|
|
* Introduction
|
|
This file contains all the variable definitions and library loading for the other files in my project.
|
|
** Straight Package Installer
|
|
I'm going to be installing everything using the [[https://github.com/raxod502/straight.el#getting-started][straight.el]] for package installation and management. Here is the initialization/installation for it:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defvar bootstrap-version)
|
|
(let ((bootstrap-file
|
|
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
|
|
(bootstrap-version 5))
|
|
(unless (file-exists-p bootstrap-file)
|
|
(with-current-buffer
|
|
(url-retrieve-synchronously
|
|
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
|
|
'silent 'inhibit-cookies)
|
|
(goto-char (point-max))
|
|
(eval-print-last-sexp)))
|
|
(load bootstrap-file nil 'nomessage))
|
|
#+END_SRC
|
|
Let's get the Straight project working with =use-package=:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(straight-use-package 'use-package)
|
|
#+END_SRC
|
|
While that enables the =:straight t= extension to =use-package=, let's just have that be the default:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package straight
|
|
:custom (straight-use-package-by-default t
|
|
straight-default-vc 'git))
|
|
#+END_SRC
|
|
See the details in [[https://dev.to/jkreeftmeijer/emacs-package-management-with-straight-el-and-use-package-3oc8][this essay]].
|
|
|
|
** OS Path and Native Compilation
|
|
Helper functions to allow code for specific operating systems:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun ha-running-on-macos? ()
|
|
"Return non-nil if running on Mac OS systems."
|
|
(equal system-type 'darwin))
|
|
|
|
(defun ha-running-on-linux? ()
|
|
"Return non-nil if running on Linux systems."
|
|
(equal system-type 'gnu/linux))
|
|
#+END_SRC
|
|
|
|
With the way I start Emacs, I may not have the PATH I /actually/ use (from the shell) available, so we'll force it (code taken [[https://www.emacswiki.org/emacs/ExecPath][from here]]):
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun set-exec-path-from-shell ()
|
|
"Set up Emacs' `exec-path' and PATH environment variable to match
|
|
that used by the user's shell.
|
|
|
|
This is particularly useful under Mac OS X and macOS, where GUI
|
|
apps are not started from a shell."
|
|
(interactive)
|
|
(let ((path-from-shell (replace-regexp-in-string
|
|
(rx (zero-or-more space) eol)
|
|
""
|
|
(shell-command-to-string "$SHELL --login -c 'echo $PATH'"))))
|
|
(setenv "PATH" path-from-shell)
|
|
(setq exec-path (split-string path-from-shell path-separator))))
|
|
|
|
(when (ha-running-on-macos?)
|
|
(set-exec-path-from-shell))
|
|
#+END_SRC
|
|
|
|
Clear up a Mac-specific issue that sometimes arises since I'm switching to [[http://akrl.sdf.org/gccemacs.html][native compilation project]], as the =Emacs.app= that I use doesn't have its =bin= directory, e.g. =Emacs.app/Contents/MacOS/bin=:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (ha-running-on-macos?)
|
|
(add-to-list 'exec-path (concat invocation-directory "bin") t))
|
|
#+END_SRC
|
|
|
|
Getting tired off all the packages that I load spewing a bunch of warnings that I can't do anything about:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(when (and (fboundp 'native-comp-available-p)
|
|
(native-comp-available-p))
|
|
(setq native-comp-async-report-warnings-errors nil
|
|
native-comp-deferred-compilation t))
|
|
#+END_SRC
|
|
** Basic Libraries
|
|
The following packages come with Emacs, but seems like they still need loading:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(require 'subr-x)
|
|
#+END_SRC
|
|
Ugh. Why am I getting a missing =first= function error? Let's just define it:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun first (elt) (car elt))
|
|
#+END_SRC
|
|
While most libraries will take care of their dependencies, I want to install /my dependent libraries/. Especially, [[https://github.com/magnars/.emacs.d/][Magnar Sveen]]'s Clojure-inspired [[https://github.com/magnars/dash.el][dash.el]] project:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package dash)
|
|
#+END_SRC
|
|
|
|
The [[https://github.com/magnars/s.el][s.el]] project is a simpler string manipulation library that I (and other projects) use:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package s)
|
|
#+END_SRC
|
|
|
|
Manipulate file paths with the [[https://github.com/rejeep/f.el][f.el]] project:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package f)
|
|
#+END_SRC
|
|
** My Code Location
|
|
Much of my more complicated code comes from my website essays and other projects. The destination, however, shows up here:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(add-to-list 'load-path (f-expand "~/.emacs.d/elisp"))
|
|
#+END_SRC
|
|
|
|
Hopefully, this will tie me over while I transition.
|
|
** Emacs Server Control
|
|
Sure the Emacs application will almost always have the =server-start= going, however, I need to control it just a bit (because I often have two instances running on some of my machines). What /defines/ the Emacs instance for work changes ... often:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun ha-emacs-for-work? ()
|
|
"Return non-nil when the Emacs application's location matches as one for work.
|
|
Currently, this is the `emacs-plus' app that I have built with
|
|
the native-comp model, but I reserve the right to change this."
|
|
(->> Info-default-directory-list
|
|
(first)
|
|
(s-split "/")
|
|
(--filter (s-starts-with? "emacs-plus" it))
|
|
(first)))
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(if (ha-emacs-for-work?)
|
|
(setq server-name "work")
|
|
(setq server-name "personal"))
|
|
|
|
(server-start)
|
|
#+END_SRC
|
|
* Load the Rest
|
|
The following loads the rest of my org-mode literate files. I add them as they are /ready/, but eventually, I'll trim this up into a nicer pattern.
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defvar ha-hamacs-files (flatten-list `("ha-private.org"
|
|
"ha-config.org"
|
|
,(when (display-graphic-p)
|
|
"ha-display.org")
|
|
"ha-org.org"
|
|
,(when (display-graphic-p)
|
|
"ha-org-word-processor.org")
|
|
"ha-org-clipboard.org"
|
|
"ha-capturing-notes.org"
|
|
"ha-agendas.org"
|
|
"ha-irc.org"
|
|
"ha-passwords.org"
|
|
"ha-remoting.org"
|
|
"ha-programming.org"
|
|
"ha-programming-python.org"
|
|
,(unless (ha-emacs-for-work?)
|
|
'("ha-org-journaling.org"
|
|
"ha-org-publishing.org"
|
|
"ha-email.org"
|
|
"ha-aux-apps.org"
|
|
"ha-feed-reader.org"))
|
|
,(when (ha-emacs-for-work?)
|
|
'("ha-org-sprint.org"
|
|
"ha-work.org"))))
|
|
"List of org files that complete the hamacs project.")
|
|
#+END_SRC
|
|
|
|
We can test/debug/reload any individual file, via:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun ha-hamacs-load (file)
|
|
"Load or reload an org-mode FILE containing literate Emacs configuration code."
|
|
(interactive (list (completing-read "Org file: " ha-hamacs-files)))
|
|
(let ((full-file (f-join hamacs-source-dir file)))
|
|
(when (f-exists? full-file)
|
|
(org-babel-load-file full-file))))
|
|
#+END_SRC
|
|
|
|
And we can now load everything:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun ha-hamacs-reload-all ()
|
|
"Reload our entire ecosystem of configuration files."
|
|
(interactive)
|
|
(dolist (file ha-hamacs-files)
|
|
(ha-hamacs-load file)))
|
|
#+END_SRC
|
|
|
|
And do it:
|
|
#+BEGIN_SRC emacs-lisp
|
|
(ha-hamacs-reload-all)
|
|
#+END_SRC
|
|
* Technical Artifacts :noexport:
|
|
Let's provide a name so that the file can be required:
|
|
|
|
#+BEGIN_SRC emacs-lisp :exports none
|
|
(provide 'bootstrap)
|
|
;;; bootstrap.el ends here
|
|
#+END_SRC
|
|
|
|
Before you can build this on a new system, make sure that you put the cursor over any of these properties, and hit: ~C-c C-c~
|
|
|
|
#+DESCRIPTION: A literate programming file for bootstrapping my environment.
|
|
|
|
#+PROPERTY: header-args:sh :tangle no
|
|
#+PROPERTY: header-args:emacs-lisp :tangle yes
|
|
#+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes
|
|
|
|
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil
|
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
|
|
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|