Reorganize first section in Emacs’ init.org

This commit is contained in:
Tom Willemse 2017-03-05 16:12:52 -08:00
parent d7a957ac6f
commit c727acf496

View file

@ -5,125 +5,147 @@ This is my personal Emacs configuration. The name was inspired by
"Ghost in the Shell 2: Man-Machine Interface and Ryan Rix's "Complete "Ghost in the Shell 2: Man-Machine Interface and Ryan Rix's "Complete
Computing Environment". Computing Environment".
To start off, first I need to enable lexical binding. * Preamble
#+BEGIN_SRC emacs-lisp :padline no These are some settings that need to be taken care of before the
;; -*- lexical-binding: t; -*- rest.
#+END_SRC
* Package configuration ** Lexical binding
Require package.el since I immediately start using its variables and To start off, first I need to enable lexical binding. It offers
functions anyway, no need to delay loading. better performance in some circumstances and enables me to use cool
things such as closures.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp :padline no
(require 'package) ;; -*- lexical-binding: t; -*-
#+END_SRC #+END_SRC
Add the MELPA and org package archives because I like living on the ** Load path
bleeding edge. This should be done both at run-time and compile-time
so I can install packages at compile time.
#+BEGIN_SRC emacs-lisp Emacs' load path is where it looks to find Emacs Lisp files when
(eval-and-compile confronted with a =load= or =require= form. Most of my packages
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) are managed through the package manager, but not all of them.
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")))
#+END_SRC
Add the directory with my mode-specific configuration files to the *** Mode-specific configuration directory
load path.
#+BEGIN_SRC emacs-lisp Add the directory with my mode-specific configuration files to the
(add-to-list 'load-path (locate-user-emacs-file "init/")) load path.
#+END_SRC
Add all my vendored packages to the load path. #+BEGIN_SRC emacs-lisp
(add-to-list 'load-path (locate-user-emacs-file "init/"))
#+END_SRC
#+BEGIN_SRC emacs-lisp *** Vendor directory
(eval-and-compile
(mapc (lambda (d) (add-to-list 'load-path d))
(directory-files
(locate-user-emacs-file "vendor-lisp/") t "^[^.]")))
#+END_SRC
Initialize package.el so that packages can be loaded and used. This Add all my vendored packages to the load path.
also needs to be done at both run-time and compile-time so packages
can be installed at compile-time.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(eval-and-compile (package-initialize)) (eval-and-compile
#+END_SRC (mapc (lambda (d) (add-to-list 'load-path d))
(directory-files
(locate-user-emacs-file "vendor-lisp/") t "^[^.]")))
#+END_SRC
Some actions produce a lot of output that is usually uninteresting *** Site lisp
during compilation. However, this information may be crucial when an
error occurs. So for these actions I can use this macro, which
stores all sent messages in a temporary buffer and prints them when
an error occurs, and hides them when it doesn't.
#+BEGIN_SRC emacs-lisp Setup everything so that any autoloads in ~site-lisp/~ get loaded
(defmacro silently (title &rest body) and can be used.
"Only output something when an error occurs.
Prefix with TITLE any output that occurs while executing BODY,
but only when an error occurs, otherwise discard it."
(declare (indent 1))
(let ((buffer-var (cl-gensym))
(error-var (cl-gensym)))
`(with-temp-buffer
(let ((,buffer-var (current-buffer)))
(cl-letf (((symbol-function 'message)
(lambda (msg &rest args)
(with-current-buffer ,buffer-var
(insert " " (apply 'format msg args) "\n")))))
(condition-case ,error-var
(progn ,@body)
(error
(princ ,(concat title " output:\n"))
(princ (with-current-buffer ,buffer-var (buffer-string)))
(princ "Error:\n")
(princ " ")
(princ (cadr ,error-var))
(princ "\n"))))))))
#+END_SRC
Refresh the package contents so packages can be installed from all #+BEGIN_SRC emacs-lisp
configured archives. Don't do this at run-time because it slows down (eval-and-compile
the process too much. (add-to-list 'load-path (locate-user-emacs-file "site-lisp/"))
(let ((loaddefs (locate-user-emacs-file "site-lisp/site-autoloads.el")))
(when (file-exists-p loaddefs)
(load loaddefs))))
#+END_SRC
#+BEGIN_SRC emacs-lisp ** Helper functions
(eval-when-compile
(let* ((not-installed (seq-remove 'package-installed-p
package-selected-packages))
(available (seq-filter (lambda (p)
(assq p package-archive-contents))
not-installed))
(difference (- (length not-installed) (length available))))
(when (> difference 0)
(silently "Refresh packages"
(package-refresh-contents)))
(when available
(mapc (lambda (p) (package-install p t)) available))))
#+END_SRC
* Site lisp Some things are best abstracted into special functions and/or
macros so as not to make the setting itself too verbose.
Setup everything so that any autoloads in ~site-lisp/~ get loaded I have some helper functions stored away in a separate file.
and can be used.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(eval-and-compile
(add-to-list 'load-path (locate-user-emacs-file "site-lisp/"))
(let ((loaddefs (locate-user-emacs-file "site-lisp/site-autoloads.el")))
(when (file-exists-p loaddefs)
(load loaddefs))))
#+END_SRC
* Helper functions
I have some helper functions stored away in a separate file.
#+BEGIN_SRC emacs-lisp
(require 'oni-helpers) (require 'oni-helpers)
#+END_SRC #+END_SRC
** Package configuration
Since Emacs 24 there has been a package manager in Emacs. A lot of
packages have been added to a number of package repositories.
*** Load the package manager
Require package.el since I immediately start using its variables
and functions anyway, no need to delay loading.
#+BEGIN_SRC emacs-lisp
(require 'package)
#+END_SRC
*** Add package archives
The default package archive has some pretty neat packages, but the
Melpa package archive is much more popular because it doesn't
require copyright assignment to upload packages to it and it is
well integrated with git.
I add these archives both at compile-time and run-time because I
install missing packages at compile-time. If the archives aren't
added then, the packages can't be installed.
**** Add Melpa
Add the Melpa package archive because I like living on the
bleeding edge.
#+BEGIN_SRC emacs-lisp
(eval-and-compile
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")))
#+END_SRC
**** Add org
Add the org package archive because it hosts the latest org
development release, and as stated above, I like living on the
bleeding edge.
#+BEGIN_SRC emacs-lisp
(eval-and-compile
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")))
#+END_SRC
*** Initialize the package manager
Initialize package.el so that packages can be loaded and used. This
also needs to be done at both run-time and compile-time so packages
can be installed at compile-time.
#+BEGIN_SRC emacs-lisp
(eval-and-compile (package-initialize))
#+END_SRC
*** Install missing packages
Refresh the package contents so packages can be installed from all
configured archives. Don't do this at run-time because it slows down
the process too much. Afterwards
#+BEGIN_SRC emacs-lisp
(eval-when-compile
(let* ((not-installed (seq-remove 'package-installed-p
package-selected-packages))
(available (seq-filter (lambda (p)
(assq p package-archive-contents))
not-installed))
(difference (- (length not-installed) (length available))))
(when (> difference 0)
(silently "Refresh packages"
(package-refresh-contents)))
(when available
(mapc (lambda (p) (package-install p t)) available))))
#+END_SRC
* Backups * Backups