Skip to content

jian-lin/nima

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nima - Configure Emacs, Declaratively and Modularly

A thin wrapper around Nixpkgs emacs.pkgs.withPackages using the module system with some footguns1 removed

Getting started

nima provides mkNima function through a Nixpkgs overlay.

mkNima takes an attribute set as argument:

{
  module ? { },
  featuresDir ? null,
  collect ? collectAllNixFiles,
  rawOutput ? false
}
  • module is a nima module.
  • featuresDir is a directory containing nima features.
  • collect is a function taking a directory and returning a list of nima feature file paths in that directory. It is used to collect nima feature files in featuresDir when featuresDir is not null. The default collect function collects all .nix files in the directory. featuresDir must be of type path when using the default collect function. You may find lib.fileset useful when writing your own collect function.
  • rawOutput defaults to false and mkNima returns a configured Emacs. When rawOutput is true, mkNima returns the raw output of lib.evalModules, which is an attribute set. Taking config.finalPackage from that attribute set and you get a configured Emacs, which is exactly the return value of mkNima when rawOutput is false. Setting rawOutput to true is for advanced use cases such as debugging by inspecting values of nima options in nix repl and modifying an already nima-configured Emacs via extendModules.

See option documentation for available module options.

Tip

There are also internal options useful for debugging. Set rawOutput to true to get access to them.

nima feature

Each file under featuresDir directory configures a nima feature.

Each file is a nima module like this

# epub.nix
{ pkgs, ... }:

{
  features.epub = {
    elisp = "...";
    epkgs = epkgs: [
      epkgs.nov
      pkgs.epub2txt2
    ];
  };
}

The feature <name> in features.<name> is almost always the same as the file name with .nix stripped. For example, in the above file, the feature is epub and the file is named epub.nix. To reduce duplication, we can also write the above file like this

# epub.nix
{ thisFeature }:

{ pkgs, ... }:

{
  features.${thisFeature} = {
    elisp = "...";
    epkgs = epkgs: [
      epkgs.nov
      pkgs.epub2txt2
    ];
  };
}

Important

{ thisFeature }: has to be written exactly like this. For example, thisFeature: does not work.

Most of the time, each feature file contains only features.<name>. In that case, we can further simplify the above file like this

# epub.nix
{ pkgs, ... }:

{
  elisp = "...";
  epkgs = epkgs: [
    epkgs.nov
    pkgs.epub2txt2
  ];
}

Tip

Module arguments, such as { pkgs, ... }:, can be omitted if not needed.

Examples

Take a look at these annotated examples to get a feeling of what nima configurations look like and how to configure a nima feature.

Try out Emacsen configured by those examples using commands like

HOME=$(mktemp -d) nix run github:jian-lin/nima#exampleSimple

Usage

See detailed usage.

Status

The author dogfoods nima and will make necessary changes in the future to keep nima working.

nima serves the author well, so presumably the author will not add new features. However, if there is a feature wanted by many people, the author may consider adding it. In addition, pull requests are welcome.

Non-goals

  • Configure early-init.el: this cannot be done in nima, but you can do it outside of nima using things like systemd.tmpfiles NixOS module option
  • Configure Emacs daemon service: this is beyond the scope of nima, which is configuring Emacs proper

Related work

details

emacs.pkgs.withPackages of Nixpkgs

Most things using Nix to configure Emacs, including nima, are wrappers of emacs.pkgs.withPackages.

If you are a happy user of emacs.pkgs.withPackages, you can continue using it.

When you want to make your Emacs configuration more modular or want some extra functionalities, have a look at its wrappers.

programs.emacs also uses the module system. nima and it have different designs, resulting in different ways to organize your Emacs configuration. nima encourages a more modular way.

In addition, nima is not tied to a specific module system while programs.emacs is part of Home Manager.

emacsWithPackagesFromUsePackage does not use the module system. As a result, nima configurations can be more modular, have better error messages and better merging behavior.

nima allows you to write Emacs configuration using the way you like, while emacsWithPackagesFromUsePackage is tied to use-package.

By focusing on use-package, emacsWithPackagesFromUsePackage can automatically find Emacs lisp package dependencies. nima cannot do that because it is impossible for configurations not using use-package.

emacsWithPackagesFromUsePackage supports writing your Emacs configuration in literate programming using Org Babel. With nima, your Emacs configuration is organized with .nix and optional .el files. Literate programming support can be added in the future if it is wanted by many people.

nima generates one single .el file from your configuration. Generally, you do not need to read that generated file. But if you do, maybe for debugging, nima has you covered with the help of outline-minor-mode to ease navigation.

License

AGPL-3.0-or-later

Footnotes

  1. Such as using emacs.pkgs.withPackages or its wrappers more than once.

About

Configure Emacs, Declaratively and Modularly

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Contributors