Skip to content

c4710n/nix-darwin-emacs

 
 

Repository files navigation

nix-darwin-emacs

A nix overlay for bleeding edge and nearly stable Emacs on Darwin (the heart of macOS).

About this overlay

Emacs

This overlay provides packages emacs-* which is:

Emacs packages

This overlay doesn’t provide any other Emacs packages, such as:

  • melpaStablePackages.*
  • melpaPackages.*
  • elpaPackages.*

If you need them, try to use overlay package provided by nix-community/emacs-overlay.

Quick Start

First, build it:

$ nix build .#emacs-29

# or
$ nix build .#emacs-unstable

Then, explore the directory result:

$ ls ./result

An example using Flake

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-23.11-darwin"; # or use newer branch

    darwin = {
      url = "github:lnl7/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    darwin-emacs = {
      url = "github:c4710n/nix-darwin-emacs";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    darwin-emacs-packages = {
      url = "github:nix-community/emacs-overlay";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs =
    { self
    , nixpkgs
    , darwin
    , darwin-emacs
    , darwin-emacs-packages
    }: {
      darwinConfigurations = {
        "current" = darwin.lib.darwinSystem rec {
          system = "aarch64-darwin"; # or "x86_64-darwin"

          modules = [
            {
              nixpkgs = {
                overlays = [
                  # 1. use `emacs` overlay provided by this repo
                  darwin-emacs.overlays.emacs
                  # 2. use `package` overlay provided by nix-community/emacs-overlay
                  darwin-emacs-packages.overlays.package
                ];
              };
            }
          ];
        };
      };
    };
}

Extra library functionality

This overlay comes with extra functions to generate an Emacs closure from various types of dependency declaration. (These are abstractions on top of emacsWithPackages.)

For example, emacsWithPackagesFromUsePackage adds packages which are required in a user’s config via use-package.

{ pkgs, ... }:
{
  environment.systemPackages = [
    (pkgs.emacsWithPackagesFromUsePackage {
      # Emacs config file.
      #
      # Supported formats:
      # + elisp source code - `*.el`
      # + org-mode babel files - `*.org`
      #
      # Note:
      # Config files cannot contain unicode characters, since they're being parsed in nix,
      # which lacks unicode support.
      #
      # elisp source code
      config = ./emacs.el;

      # or, org-mode babel files
      # config = ./emacs.org;

      # Whether to include your config as a default init file.
      # If being bool, the value of config is used.
      # Its value can also be a derivation like this if you want to do some
      # substitution:
      #   defaultInitFile = pkgs.substituteAll {
      #     name = "default.el";
      #     src = ./emacs.el;
      #     inherit (config.xdg) configHome dataHome;
      #   };
      defaultInitFile = true;

      # Package is optional, defaults to pkgs.emacs-unstable
      package = pkgs.emacs-29;

      # By default emacsWithPackagesFromUsePackage will only pull in
      # packages with `:ensure`, `:ensure t` or `:ensure <package name>`.

      # For Org mode babel files, by default only code blocks with
      # `:tangle yes` are considered. Setting `alwaysTangle` to `true`
      # will include all code blocks missing the `:tangle` argument,
      # defaulting it to `yes`.
      # Note that this is NOT recommended unless you have something like
      # `#+PROPERTY: header-args:emacs-lisp :tangle yes` in your config,
      # which defaults `:tangle` to `yes`.
      alwaysTangle = true;

      # Optionally provide extra packages not in the configuration file.
      extraEmacsPackages = epkgs: [
        epkgs.cask
      ];

      # Optionally override derivations.
      override = final: prev // {
        weechat = prev.melpaPackages.weechat.overrideAttrs(old: {
          patches = [ ./weechat-el.patch ];
        });
      };
    })
  ];
}

Similarly, emacsWithPackagesFromPackageRequires adds packages which are declared in a .el package file’s Package-Requires header, which can be handy for CI purposes:

# ...
let
  emacsForCI = pkgs.emacsWithPackagesFromPackageRequires {
    packageElisp = builtins.readFile ./flycheck.el;
    extraEmacsPackages = epkgs: [
      epkgs.package-lint
    ];
  };
pkgs.mkShell {
  buildInputs = [ emacsForCI ];
}

License

MIT

About

A nix overlay for bleeding edge and nearly stable Emacs on Darwin (the heart of macOS).

Resources

Stars

Watchers

Forks

Releases

No releases published

Languages

  • Nix 100.0%