Background

Configuring Emacs can get complicated especially when you want your configuration to be cross-platform (to run without any issues on FreeBSD, Linux, OpenBSD, OS X and Windows) and work in both terminals and graphical user interfaces. If your Emacs Lisp code is long and complicated, you might become reluctant to modify or add functionality to Emacs due to the possibility of breaking your existing configuration and ultimately wasting your time. decl.el is an attempt to alleviate some of these problems when configuring Emacs using Emacs Lisp.

Usage

  1. Logically separate Emacs Lisp code portions in your configuration files by the functionality that they add or modify within Emacs. Keep note of any dependencies that those portions of code may have.

  2. Wrap all of these separate portions of Emacs Lisp code in lambda functions that return a truthy value (non-nil) upon successful execution and return nil upon failure. If any lambda function throws an error upon execution, it is considered to have not executed successfully, equivalent to if it were to return nil.

  3. Create a decl-block and assign it a keyword name.

  4. For each lambda function, create a decl-node to place it in. Give each decl-node a keyword name, the keyword name of the decl-block that it belongs to, the lambda function to be placed within it, and optionally a list of the keyword names of the decl-nodes housing the lambda function's dependencies, all in the stated order. The dependencies of a lambda function are other lambda functions which must execute successfully in order for the lambda function to be executed successfully.

  5. Solve the decl-block.

Optionally, use the interactive function decl-report for a report in an Org-mode buffer that describes how the decl-block was solved.

Example

The following example assumes that you have installed this package via http://melpa.org/ (alternatively just download and include the decl.el file manually from https://github.com/preetpalS/decl.el/):

;;; init.el --- sample init.el using library

(package-initialize)
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)

(add-hook 
 'after-init-hook
 (lambda () "Your init file"
   (require 'decl)
   (decl-block :init)
   (decl-node :mac-osx :init (lambda () (eq system-type 'darwin)))
   (decl-node :windows :init (lambda () (eq system-type 'windows-nt)))
   (decl-node :linux :init (lambda () (eq system-type 'gnu/linux)))
   (decl-node :gui :init (lambda () (if window-system t nil)))
   (decl-node :mac-osx-fullscreen-supprt :init
              (lambda ()
                (defun toggle-fullscreen (&optional f)
                  (interactive)
                  (let ((current-value (frame-parameter nil 'fullscreen)))
                    (set-frame-parameter nil 'fullscreen
                                         (if (equal 'fullboth current-value)
                                             (if (boundp 'old-fullscreen) old-fullscreen nil)
                                           (progn (setq old-fullscreen current-value)
                                                  'fullboth)))))
                t)
              '(:gui :mac-osx))
   (decl-node :windows-consolas :init
              (lambda ()
                (set-face-attribute 'default nil :font "consolas-14:antialias=natural"))
              '(:windows :gui))
   (decl-solve :init)
   ; Optionally execute for a report on the solver's execution: (decl-report :init)
   ))

(provide 'init)

;;; init.el sample ends here