Reorganize first section in Emacs’ init.org
This commit is contained in:
parent
d7a957ac6f
commit
c727acf496
1 changed files with 121 additions and 99 deletions
|
@ -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
|
||||
Computing Environment".
|
||||
|
||||
To start off, first I need to enable lexical binding.
|
||||
* Preamble
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :padline no
|
||||
;; -*- lexical-binding: t; -*-
|
||||
#+END_SRC
|
||||
These are some settings that need to be taken care of before the
|
||||
rest.
|
||||
|
||||
* Package configuration
|
||||
** Lexical binding
|
||||
|
||||
Require package.el since I immediately start using its variables and
|
||||
functions anyway, no need to delay loading.
|
||||
To start off, first I need to enable lexical binding. It offers
|
||||
better performance in some circumstances and enables me to use cool
|
||||
things such as closures.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(require 'package)
|
||||
#+END_SRC
|
||||
#+BEGIN_SRC emacs-lisp :padline no
|
||||
;; -*- lexical-binding: t; -*-
|
||||
#+END_SRC
|
||||
|
||||
Add the MELPA and org package archives because I like living on the
|
||||
bleeding edge. This should be done both at run-time and compile-time
|
||||
so I can install packages at compile time.
|
||||
** Load path
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(eval-and-compile
|
||||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
||||
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")))
|
||||
#+END_SRC
|
||||
Emacs' load path is where it looks to find Emacs Lisp files when
|
||||
confronted with a =load= or =require= form. Most of my packages
|
||||
are managed through the package manager, but not all of them.
|
||||
|
||||
Add the directory with my mode-specific configuration files to the
|
||||
load path.
|
||||
*** Mode-specific configuration directory
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'load-path (locate-user-emacs-file "init/"))
|
||||
#+END_SRC
|
||||
Add the directory with my mode-specific configuration files to the
|
||||
load path.
|
||||
|
||||
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
|
||||
(eval-and-compile
|
||||
(mapc (lambda (d) (add-to-list 'load-path d))
|
||||
(directory-files
|
||||
(locate-user-emacs-file "vendor-lisp/") t "^[^.]")))
|
||||
#+END_SRC
|
||||
*** Vendor directory
|
||||
|
||||
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.
|
||||
Add all my vendored packages to the load path.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(eval-and-compile (package-initialize))
|
||||
#+END_SRC
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(eval-and-compile
|
||||
(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
|
||||
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.
|
||||
*** Site lisp
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defmacro silently (title &rest body)
|
||||
"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
|
||||
Setup everything so that any autoloads in ~site-lisp/~ get loaded
|
||||
and can be used.
|
||||
|
||||
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.
|
||||
#+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
|
||||
|
||||
#+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
|
||||
** Helper functions
|
||||
|
||||
* 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
|
||||
and can be used.
|
||||
I have some helper functions stored away in a separate file.
|
||||
|
||||
#+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
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(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
|
||||
|
||||
|
|
Loading…
Reference in a new issue