Grail loads an .emacs configuration by looking into a directory tree, instead of loading a single monolothic .emacs. There are many good reasons to do this, and some powerful features:
Grail is grew out of a tidyconfig like need to re-organize after a .emacs bankrupcy. It has grown beyond organization alone into a comprehensive management of load-path, porting configurations between linux & Darwin, and partial/incremental loading to configure for batch, interactive, gui, and daemon modes.
I wrote Grail simply because I need it. I have Emacs on several different machines and operating systems. I need some elisp loaded on OSX, some on debian, gentoo etc. I need Emacs to work on a TTY or a GUI without barfing, and I love --daemon when I can use it.
The advanced profiles support came out of a need to simply have a single configuration in a tarball/version-control and have all the third party stuff automatically installed when it is not there for some reason. I think stuffing other people’s packages into my version-control is in bad taste, so I needed an install option.
ELPA is the future, and will be in a future emacs (more proof), so I support it as the best way to install third party stuff.
Grail replaces your .emacs, and loads your configuration. You put your configuration in the places where grail looks for things. You can start by putting everything into user.el, or make it as fine-grained as you need so emacs always starts correctly.
Examples of the files grail looks for:
Grail loads things in a certian order that has been refined over time to keep your sanity. If these places do not exist, they are not placed in load-path. Only what you use ends up in load-path.
1. local/emacs/ The directory containing Emacs packages that over-ride emacs distributed files.
2. local/elisp/ The directory containing Emacs libraries created and maintained by the user.
3. dist/ The directory for managing distributed packages
4. dist/elisp/ The directory containing third-party elisp extensions of Emacs
5. dist/elpa ELPA managed third party elisp.
6. dist{cvs,git,svn} version control managed third party elisp
Once you have installed grail simply execute the command: grail-install-elpa. Enjoy the excellent work of Tromney with package-list-packages. Grail will make sure that ELPA is installed in the right places.
Enjoy Grail, and feel free to give feedback, with the contact information provided on codermattie.
I love squasing bugs ! you find them … I kill them !
This release is significant in that it supports the next generation ELPA package.el. It has been tested against Emacs 23 & 24. It has also been tested successfully on windows finally !
Some small bugs have been fixed as well. This release does not have any serious code churn indicating that the code-base is maturing well.
Grail is also now hosted on github so others can easily contribute more easily.
It works reliably for me on Gentoo & Debian. It was tested on OSX previously, but my mac is dead. If it works for you please let me know so I can report the platforms it works on.
At this point the major work is done on this project. What remains is documenting the API’s and how to use the grail-profile feature set.
These install instructions assume you already have a .emacs configuration.
1. choose a location where your Emacs configuration will live. This directory will be called $USER_ELISP.
2. download the grail files from the download links above to $USER_ELISP
3. copy your .emacs to $USER_ELISP/user.el
4. copy/extract the customize generated settings to $USER_ELISP/customize-settings.el
5. make link from ~/.emacs → $USER_ELISP/grail.el
you can now start Emacs with Grail loading your config
6. start emacs like this:
USER_ELISP=<where you put grail and your config> emacs
7. Look at the diagram of USER_ELISP in the next section and organize your configuration to your taste.
This is a simple diagram of what the USER_ELISP directory looks like when all of the Grail recognized files and directories are in place.
When a directory has a (++) next to it Grail will add any sub-directories beneath that directory, as well as the directory itself to load-path.
The diagram also shows which modes load the special files. As you can see only elisp.el, and gui.el are truly special in that they are loaded differently from the others.
The files like commands.el, and keys.el are opportunities to organize, they are not required.
display.el and gui.el are delayed in --daemon mode. display.el is loaded before the first frame (TTY/GUI) is created, and gui.el after the first GUI frame is created.
This delay insures that the GUI is actually loaded before the user’s customizations are loaded.
|-- grail.el ;; grail files |-- grail-fn.el |-- grail-profile.el | |-- darwin.el ;; platform specific files, loaded only on Darwin or Gnu/Linux. |-- linux.el |-- windows.el | |-- customize-settings.el ;; where customize scribbles | |-- elisp.el |BATCH,all| ;; A library of Elisp functions loaded in both batch and interactive mode. | |-- user.el |TTY,GUI| ;; user configuration of Emacs. All the stuff built into Emacs Tramp,VC,Ediff,... |-- interface.el |TTY,GUI| ;; general interface issues (in mine turning off the menu bar etc...) | |-- commands.el |TTY,GUI| ;; The user's collection of commands. |-- keys.el |TTY,GUI| ;; The user's key bindings. | | *** delayed for daemon mode *** |-- display.el |TTY,GUI| ;; Configuration for a TTY or graphical frame. |-- gui.el |GUI| ;; Configuration for a graphical frame. | *** delayed for daemon mode *** | |-- customize-settings.el |TTY,GUI| ;; Settings written by customize and Emacs. |-- dist | |-- elisp (++) | | `**Downloaded Elisp** ;; download Elisp files, and packages with directories are found here. | `-- elpa ;; ELPA maintained packages are installed here. | |-- local | |-- elisp (++) ;; the user's Elisp is searched for in local/elisp. | | `**your Elisp** | |-- emacs ;; modified copies of files distributed with Emacs. | `-- profiles ;; profile configuration modules are found here.
Profiles allow configuration snippets that depend on third-party code to download the third-party code, load, and resume the startup of Emacs.
Here is an example of a profile from my configuration that loads all of my lisp programming settings.
(grail-load 'mic-paren (grail-define-installer "mic-paren"
"file"
"http://www.emacswiki.org/cgi-bin/emacs/download/mic-paren.el"))
(grail-load 'quack (grail-define-installer "quack"
"file"
"http://www.neilvandyke.org/quack/quack.el"))
(grail-load 'slime (grail-define-installer "slime"
"cvs"
":pserver:anonymous:anonymous@common-lisp.net:/project/slime/cvsroot"))
(setq
paren-showing t
show-paren-style 'parenthesis
show-paren-delay 1
paren-sexp-mode 'match)
When I copy my configuration to a new machine I simply copy this “profile” file and start Emacs. When Emacs starts Grail detects that the packages are missing before the configuration bits runs. Grail installs the packages, adjusts load-path as needed, and attempts a second load of the package.
It is almost this simple ! profiles are not automatically loaded just because they are in the profiles directory. I also place this command in one of the special files grail loads.
(use-grail-profiles 0 "template" "lisp" "code-formatting" "sql")
This is in a file automatically loaded by Grail. It is a list of the profiles that Grail should load. The first value is a digit indicating the loading priority. 0 is the highest priority while higher numbers are lower priorities. The profiles are loaded in highest to lowest priority.
All of the profiles are loaded at the very end of the startup process so the configuration bits in the profile files can use the definitions from everything loaded previously.
Here are some examples of my profiles:
Here is the documentation string for grail-define-installer
(defun grail-define-installer ( name type &rest url-list )
"grail-define-installer NAME TYPE &rest URLS
define a installer for a package NAME.
The type of the installer indicates the format of the URL.
TYPE is the format of the URL for handling things like
compression,archives, and RCS systems.
recognized TYPE's : file, tar:bz2, tar:gz, cvs svn git
download a plain elisp file: (grail-define-installer \"bob\" \"file\" \"URL\")
download an tar.bz2 archive: (grail-define-installer \"bob\" \"tar:bz2\" \"URL\")
cvs checkout: : (grail-define-installer \"bob\" \"cvs\" \"pserver\")
Most of the time a single URL suffices. Many packages are a
single elisp file, or a single tarball.
Other packages such as icicles are several elisp files, or
possibly several archives.
In this case a list of cons pairs can be given as the
URL. When this happens NAME becomes a sub-directory they are
installed to, and the files a list of (name . url) pairs.
(grail-define-installer PACKAGE \"file\"
'(\"foo.el\" . \"URL\")
'(\"bar.el\" . \"URL\")
this would install as:
PACKAGE/foo.el
PACKAGE/bar.el
"
Q: What should I set ‘custom-file’ to, i.e., where should I store my customizations?
A: As of the grail-0.1.3 Grail handles customizations.
It looks in the variable "grail-settings-file" which points to USER_ELISP/customize-settings.el by default.
It will change both "user-init-file" and "custom-file" to point at your "grail-settings-file" when grail starts.
If you have used Grail and customize before 0.1.3 it has likely written customize settings to grail.el itself which is not fatal, but not good.
To upgrade to grail-0.1.3 you need to edit grail.el, or whatever other files have these customize settings, and migrate them to customize-settings.el
I will ponder a migration tool if I can come up with something safe.