Dot is a collective configuration system which contains configurations for programs like Emacs and zsh, but also (potentially) Vim. Dot is written under the following principles:
- Configurations should only be run if necessary—that is, if the user wants it.
- Configurations should be as lean, modular, and standalone as possible, utilizing autoload and byte compilation mechanisms whenever possible and only running what is necessary.
- Configurations should be clean, well-documented, and consistently-written throughout.
- Configurations should have a focus on truly excellent support for everything.
- Configurations should also have clear error messages handling common PEBKAC errors.
You can use this command to install our configuration. (Ruby must be installed for this to work, so make sure you have done that.)
$ \ruby -e "$(\curl -fsSL https://raw.githubusercontent.com/kotct/dot/master/scripts/install)"
This script will interactively ask you if there are any conflicts or decisions to be made, but will immediately start installing the configuration, so make sure that you are sure of what you want to do.
This script assumes a fairly regular system with the requisite
software installed, so if you are in an esoteric environment, you can
plan on manually installing this by symlinking into ~
. If something
breaks down on a normal system, (like Ubuntu, Fedora) please open an
Issue and we will get back to you ASAP.
If your system is running an older version of a dependency software, (i.e. Emacs < 25.1, Ruby < 2.4) please do your best to update to the latest version directly available from your package manager. If an issue is not reproducible on our system, we cannot fix it.
It is worth noting that you should be able to simply simlink the
respective files and directories into your HOME
directory.
You can do this by cloning this repository, then running:
$ bundle install
$ rake install
This is effectively what the above script does, except it allows you to clone to your own desired location.
The Emacs configuration is the primary focus of this project and is the defining feature of this project. Most of the work done here will be done on the Emacs configuration, as the primary goal in writing this configuration is and was to write a robust, fast, and efficient Emacs configuration.
Below is included the discussion about the rewrite of the Emacs configuration, which will take place in this repository.
Create fast configurations for common developer tools with a clean, unified style, that has IDE-level support for many languages.
In addition, the following guidelines apply to our Emacs configuration:
- Autoload things as much as possible—that is, load as little as possible on startup so as to minimize start-up time.
- Automatically byte-compile on start.
- Use a clean, consistent EmacsLISP style.
- Have a focus on excellent support for individual languages.
- Make sure everything is well-thought-out and well-documented.
- Have clear error messages handling most user fuck-ups.
To create a personal config, create a personal, public GitHub repo
called .emacs
. Emacs may prompt you to add a "personal config" on
start. If your emacs is already up and running, and no longer prompts
you as such, you can add your personal config by doing
M-x kotct/user-set-default-username
. Emacs will automatically grab
your config from GitHub and load it. The clone that emacs uses is
stored in a directory named after your GitHub username in
.emacs.d/lisp/user/users/
.
To update the clone of your personal config, do
M-x kotct/user-update-config
. In addition, to switch to another user
config, do C-x C-z
.
Within the base .emacs.d
directory, the only checked-in emacs lisp
file is init.el
. This file contains any code that must be loaded
before the elisp hubs and any code that manages loading, autoloading,
or byte compilation.
All other codes is organized into directories based on language. For
instance, all emacs lisp code goes into the lisp
directory, and ruby
or python code goes into the ruby
and python
directories,
respectively.
The lisp
directory contains a directory for each "hub". Within each
hub directory is a <hub-name>-hub.el
directory containing the hub
definition (using the kotct/hub
function). Each file within the hub
that is loaded at startup should provide a feature with a simple name
(e.g. "startup", "backup", or "recentf-c"). If the file is
configuring another package, name it <package>-c
(as in "recentf-c"
above), with "c" standing for "configuration." Try to avoid this "-c"
suffix when possible.
Autoloaded files should contain at least one function or other symbol
whose definition is preceded by an autoload token (;;;###autoload
).
At the top of the file, include the following comment:
;;; THIS FILE IS NOT LOADED AT STARTUP.
;;; This file is autoloaded on the following symbols:
;;; kotct/function1
;;; kotct/function2
To make sure the file is checked for autoloads, ensure that in the
hub file's call to kotct/hub
, the final argument is 'autoloads
.
Calls to autoload
will be automatically generated and saved in
lisp/kotct-loaddefs.el
and loaded on startup.
Generally, calls to require
should be avoided, since these calls
will sometimes force loading of features that would otherwise be
autoloaded. Cases can occur in which a require
is appropriate, for
instance, if the package does not have autoloads or an autoload will
be triggered later in the file anyway.
If an autoloaded package needs configuration, instead of using
require
to load the package in order to configure it, wrap the
configuration in a with-eval-after-load
block so that it will only
be loaded after the package is autoloaded.
All files are automatically bytecompiled asynchnonously after emacs
starts. This aims to be a totally hands-off experience. That said,
any files more than one subdirectory below the lisp/
directory
need to be manually added to kotct/files-to-compile
, which keeps
track of all the files that are to be byte compiled.
Keybindings should be located at whatever places makes sense. Most commonly, they will be located after the definition of the function they are binding, or after relevant configuration.
To globally bind a key, use a line such as:
(global-set-key (kbd "C-x C-r") #'kotct/ido-recentf-open)
At the top of any file with keybindings, add a comment like the following for each keybinding:
;;; C-x C-r: find recent files and directories using recentf
The only assumptions we can make about our environment are that we are using a certain minimum version of emacs (tbd) and we have all package dependencies installed (although we should handle the case at startup where not all dependencies are installed).
Things we CANNOT assume:
- We are using a POSIX-compliant OS.
- We have external dependencies installed (such as Ruby or Python).
- The user is not an idiot.
Up for debate:
- Can we assume we are not running from a terminal (i.e. can we design so that some functionality may not be present when running from a terminal)?
- Prefix all global function or variable names with
kotct/
, as inkotct/ido-recentf-open
orkotct/hub-names
. - Always use
setf
instead ofsetq
.setq
should never be used in this project. - When referencing a function name, always use a function quote (
#'
) instead of a regular quote ('
). This function quote (or funquote) translates to a call tofunction
instead ofquote
. - As described in
the Autoloading section,
avoid
require
and usewith-eval-after-load
. - Make sure all
defun
s,defvar
s, anddefmacro
s (and any other global definitions) have docstrings that are properly formatted. - Comment when it's not immediately clear what the code is doing.
- Write modular, clean, and fast code.
dot
is released and distributed under the terms of the MIT license.
See LICENSE
for
more information.