dotfiles/emacs/.emacs.d/init.el
Tom Willemse 85a3512b05 Improve ensure-package macro
- Rename to “ensure-library”, since I’m really trying to make sure a
  certain library is installed and calling something like the following
  is just silly:

    (ensure-package geiser-impl :package geiser)

- Rename the “:from” keyword parameter to “:package” since it is
  ambiguous when a “:path” keyword parameter is added, which could also
  be considered to determine from where a library is loaded.

- Add the “:path” keyword parameter, some libraries aren’t managed by
  package.el but by me. This parameter adds its value to the load path
  before attempting to check if it has been installed.

- Instead of checking if the package is installed and can be located,
  just try requiring it. This is easier for libraries not managed by
  package.el, since they will technically not be installed.
2016-07-25 22:07:47 +02:00

188 lines
6.3 KiB
EmacsLisp

;;; init.el --- Tom-Emacs Interface -*- lexical-binding: t; -*-
;; Copyright (C) 2016 Tom Willemse
;; Author: Tom Willemse <tom@ryuslash.org>
;; Keywords: local
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; 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".
;;; Code:
;;;; Package configuration:
;;; Require package.el since we immediately start using its variables
;;; and functions anyway, no need to delay loading.
(require 'package)
;; 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.
(eval-and-compile
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")))
;; 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.
(eval-and-compile (package-initialize))
;; 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.
(eval-when-compile (package-refresh-contents))
;; This macro is inspired by use-package, but I want to maintain some
;; control of the syntax I use to configure my settings.
(defmacro ensure-library (library &rest args)
"Make sure LIBRARY is installed.
ARGS should be a plist which may contain one of the following options:
- :package
Specify which package should actually be installed to ensure
the library named in LIBRARY exists.
- :path
Specify a path to add to the load path to be able to load this
package."
(declare (indent 1))
(let ((library-symbol (cl-gensym))
(package-symbol (cl-gensym))
(path-symbol (cl-gensym))
(package (or (plist-get args :package) library))
(path (plist-get args :path)))
`(progn
(eval-and-compile
(let ((,path-symbol ,path))
(if ,path-symbol
(add-to-list 'load-path
(if (file-name-absolute-p ,path-symbol)
,path-symbol
(concat user-emacs-directory ,path-symbol))))))
(eval-when-compile
(let ((,library-symbol ',library)
(,package-symbol ',package))
(unless (require ,library-symbol nil :noerror)
(package-install ,package-symbol)
(require ,library-symbol)))))))
;;;; Helper functions:
;; I have noticed that I refer to the combination of
;; `user-emacs-directory' and "data/" a lot, so I wrote this function
;; to make referencing it cleaner. Also useful if I ever want to move
;; my data directory.
(defun oni:data-location (file-name)
"Return the location of FILE-NAME within my data directory.
This is currently the data directory under the
`user-emacs-directory'."
(concat user-emacs-directory "data/" file-name))
(ert-deftest oni:data-location ()
"Test that `oni:data-location' returns the correct locations."
(should (string= "~/.emacs.d/data/backup-files/"
(oni:data-location "backup-files/")))
(should (string= "~/.emacs.d/data/auto-save-files/"
(oni:data-location "auto-save-files/")))
(should (string= "~/.emacs.d/data/auto-save-list/.saves-"
(oni:data-location "auto-save-list/.saves-"))))
;;;; Backups:
;; I don't like having every directory filled with "filename~"
;; files. So instead of saving backup files to the same directory,
;; save them to a special one instead.
(setq backup-directory-alist `((".*" . ,(oni:data-location "backup-files/"))))
;;;; Auto saves:
;; I prefer to keep all autosave files in a single directory so they
;; don't clog up my filesystem so much. Usually these files get
;; deleted, but sometimes they don't, and I don't think they look
;; pretty. Add it to the end of the list because the default value
;; stores auto-saves for remote files in /tmp, which is fine by me.
(add-to-list 'auto-save-file-name-transforms
`(".*" ,(oni:data-location "auto-save-files/") t) :append)
;; Place the files which contain the auto save files in a similar
;; directory.
(setq auto-save-list-file-prefix (oni:data-location "auto-save-list/.saves-"))
;;;; Tabs:
;; Generally I prefer using spaces over tabs. Especially for lisp-like
;; languages.
(setq-default indent-tabs-mode nil)
;; A tab-width of 8 is too wide for me, and 2 is too narrow. 4 is just
;; right.
(setq-default tab-width 4)
;;;; Font:
(defvar oni:preferred-font "Fantasque Sans Mono-13"
"My personally preferred font.")
;; This sets the font for normal Emacs sessions. This will change the
;; font for all _existing_ frames, any future frames will not be
;; affected by this.
(set-frame-font oni:preferred-font nil t)
;; This sets the font for Emacs daemon-mode sessions. This changes the
;; font for all _future_ frames, but doesn't change anything for the
;; currently existing frames.
(add-to-list 'default-frame-alist `(font . ,oni:preferred-font))
;;;; Menu bar:
;; I don't use the menu bar, so it just takes up space.
(menu-bar-mode -1)
;;;; Tool bar:
;; I don't use the tool bar, so it just takes up space.
(tool-bar-mode -1)
;;;; Scroll bar:
;; I don't use the scroll bar to either navigate my buffers or see
;; whereabouts I am, so they just take up space.
(scroll-bar-mode -1)
;;;; Minor modes:
;;;;; Paredit:
(ensure-package paredit)
;;;; Major modes:
;;;;; Scheme mode:
(add-hook 'scheme-mode-hook 'paredit-mode)
;;;; Applications:
;;;;; Magit:
(ensure-package magit)
(provide 'init)
;;; init.el ends here