diff --git a/README.md b/README.md index 974124d3..576d343f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +| index | | | +| --- | --- | --- | +|**readme**|[reference](./docs/reference.md)|[faq](./docs/faq.md)| + # nix-doom-emacs | | Status | @@ -6,8 +10,7 @@ | Dependency updater | [![Dependency Updater Status](https://github.com/nix-community/nix-doom-emacs/workflows/Update%20Dependencies/badge.svg?branch=master)](https://github.com/nix-community/nix-doom-emacs/actions/workflows/update-dependencies.yml?query=branch%3Amaster) | | Matrix Chat | [![Matrix Chat](https://img.shields.io/static/v1?label=chat&message=doom-emacs&color=brightgreen&logo=matrix)](https://matrix.to/#/#doom-emacs:nixos.org) | -Nix expression to install and configure -[doom-emacs](https://github.com/doomemacs/doomemacs). +nix-doom-emacs (abbreviated as NDE) provides a customisable Nix derivation for [Doom Emacs](https://github.com/doomemacs/doomemacs). The expression builds a `doom-emacs` distribution with dependencies pre-installed based on an existing `~/.doom.d` directory. @@ -17,121 +20,20 @@ some may not be fully compatible as the version available in NixOS or [emacs-overlay](https://github.com/nix-community/emacs-overlay) may not be compatible with the `doom-emacs` requirements. -## Getting started - -Using [home-manager](https://github.com/nix-community/home-manager): - -``` nix -{ pkgs, ... }: - -let - doom-emacs = pkgs.callPackage (builtins.fetchTarball { - url = https://github.com/nix-community/nix-doom-emacs/archive/master.tar.gz; - }) { - doomPrivateDir = ./doom.d; # Directory containing your config.el init.el - # and packages.el files - }; -in { - home.packages = [ doom-emacs ]; -} -``` - -`./doom.d` should contain the following three files: `config.el`, `init.el` and -`packages.el`. If you don't already have an existing `doom-emacs` configuration, -you can use the contents of `test/doom.d` as a template. - -Using `flake.nix`: - -``` nix -{ - inputs = { - home-manager.url = "github:nix-community/home-manager"; - nix-doom-emacs.url = "github:nix-community/nix-doom-emacs"; - }; - - outputs = { - self, - nixpkgs, - lib, - home-manager, - nix-doom-emacs, - ... - }: { - nixosConfigurations.exampleHost = lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - home-manager.nixosModules.home-manager - ({ - home-manager.users.exampleUser = lib.mkMerge [ - nix-doom-emacs.hmModule - { ... }: { - programs.doom-emacs = { - enable = true; - doomPrivateDir = ./doom.d; - }; - } - ]; - }) - ]; - }; - }; -} -``` - -## Under the hood - -This expression leverages -[nix-straight.el](https://github.com/nix-community/nix-straight.el) under the hood for -installing dependencies. The restrictions of that package apply here too. - -## Usage - -instead of running emacs.d/bin/doom, once you have update your config files (packages.el, init.el, config.el), rebuild doom-emacs with nix. If you are using home-manager, simply run `home-manager switch` - -## Troubleshooting - -On macOS on a fresh install, you might run into the error `Too many files open`. running `ulimit -S -n 2048` will only work for the duration of your shell and will fix the error - -## Installing emacs packages - -In the initial packages.el instructions for how to install packages can be -found. However some packages might require a particular software dependency to -be installed. Trying to install those would give you an error of the type: -`Searching for program: No such file or directory, git` (Missing git dependency) -Here is how you would go installing -[magit-delta](https://github.com/dandavison/magit-delta) for example (which -requires git). - -Under the line: -`doomPrivateDir = ./doom.d;` -in your configuration, you would add the following: - -```Nix -{ - emacsPackagesOverlay = self: super: { - magit-delta = super.magit-delta.overrideAttrs (esuper: { - buildInputs = esuper.buildInputs ++ [ pkgs.git ]; - }); - }; -} -``` +# Quick Start -To make the git dependency available. trying to rebuild doom-emacs with -`home-manager switch` should work correctly now. +If you want to get a taste of nix-doom-emacs, you can run ``nix run github:nix-community/nix-doom-emacs`` +Which will run nix-doom-emacs with an example configuration. -## Using the daemon +Pick which setup you're using here (if you're not using NixOS or Home-Manager, then you should use standalone): -To use the daemon, simply enable the emacs service (with `NixOS`, `home-manager` -or `nix-darwin`) and use the doom emacs package. `doom-emacs` will need to be -referenced at the top of your config file. +| Home-Manager | NixOS | Standalone | +| --- | --- | --- | +| [Flake + Home-Manager](./docs/reference.md#home-manager) | [NixOS](./docs/reference.md#nixos) | [Standalone](./docs/reference.md#standalone) | -```nix -{ - services.emacs = { - enable = true; - package = doom-emacs; # Not needed if you're using the Home-Manager module instead - }; -} -``` +# Hacking -to connect to the daemon you can now run `emacsclient -c` +This project is under MIT license. Our [issue tracker](https://github.com/nix-community/nix-doom-emacs/issues) has some open issues, +the `PR wanted` label is for issues that need PRs to fix them. +Also, talk to us in the [Matrix Chat](https://matrix.to/#/#doom-emacs:nixos.org) to discuss ideas for future improvements. +Contributions are welcome. diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 00000000..941d7744 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,61 @@ +| index | | | +| --- | --- | --- | +|[readme](../README.md)|[reference](./docs/reference.md)|**faq**| + +# Frequently Asked Questions + +## I am new to Nix. Is this the only way to use Doom Emacs with Nix/NixOS? + +Nope! Doom Emacs is still perfectly usable imperatively. In fact, the very author of Doom Emacs uses NixOS and install Doom Emacs with an ["imperative" setup](https://github.com/hlissner/dotfiles/blob/master/modules/editors/emacs.nix). You can follow the instructions on the [Doom Emacs GitHub repository](https://github.com/doomemacs/doomemacs) to get a working setup. + + +## How do I add a non-(M)ELPA dependency to a package's build? + +You'd usually need to do this when a (M)ELPA pakage needs some package to exist on your system, like `git` for example. + +You should use the `emacsPackagesOverlay` attribute. Here's an example that installs `magit-delta`, which depends on Git: + +```nix +programs.doom-emacs = { + # ... + emacsPackagesOverlay = self: super: { + magit-delta = super.magit-delta.overrideAttrs (esuper: { + buildInputs = esuper.buildInputs ++ [ pkgs.git ]; + }); + } +}; +``` + +## How do I add a package that's only on GitHub (or any Git frontend) + +If you try to add a package that isn't from (M)ELPA, you'd get this error: `Package not available`. This is because `nix-straight.el` assumes that packages are on emacs-overlay's packages, which only include (M)ELPA. +This question assumes the package uses GitHub, so it uses the `fetchFromGitHub` function. To see which function you'd need to use, you should look at [the Nixpkgs manual's fetchers section](https://nixos.org/manual/nixpkgs/stable/#chap-pkgs-fetchers) +For an example, this installs `idris2-mode` which isn't on (M)ELPA, but is hosted on GitHub: + +```nix +programs.doom-emacs = { + # ... + emacsPackagesOverlay = self: super: { + idris2-mode = self.trivialBuild { + pname = "idris2-mode"; + ename = "idris2-mode"; + version = "unstable-2022-09-21"; + buildInputs = [ self.prop-menu ]; + src = pkgs.fetchFromGitHub { + owner = "idris-community"; + repo = "idris2-mode"; + rev = "4a3f9cdb1a155da59824e39f0ac78ccf72f2ca97"; + sha256 = "sha256-TxsGaG2fBRWWP9aas59kiNnUVD4ZdNlwwaFbM4+n81c="; + }; + }; + } +}; +``` + +## nix-doom-emacs isn't working if I set DOOMDIR or EMACSDIR + +You shouldn't do that. nix-doom-emacs' home-manager module writes `~/.emacs.d` in your `$HOME`. Make sure to remove the environment variables from your configuration, then reboot after rebuilding it. If for just the session, you can just `unset` those 2 variables. + +## It errors with "Too many files open"! + +Running `ulimit -S -n 2048` will fix it for the duration of your shell session. diff --git a/docs/reference.md b/docs/reference.md new file mode 100644 index 00000000..296a1366 --- /dev/null +++ b/docs/reference.md @@ -0,0 +1,242 @@ +| index | | | +| --- | --- | --- | +|[readme](../README.md)|**reference**|[faq](./docs/faq.md)| + +# nix-doom-emacs reference + +nix-doom-emacs uses [`nix-straight.el`](https://github.com/nix-community/nix-straight.el) under the hood to install dependencies. It's a low level wrapper to integrate Nix with [`straight.el`](https://github.com/radian-software/straight.el). It is maintained by the same people as this project. + +Currently, `nix-straight.el` only extracts package names and uses [`emacs-overlay`](https://github.com/nix-community/emacs-overlay) to obtain the package sources. This works most of the time but occasionally results in obscure issues with recently updated packages. + +# Getting Started + +In all of these methods, you'll need your Doom Emacs configuration. It should contain the following three files: +`config.el`, `init.el` and `packages.el`. If you don't already have an existing `doom-emacs` configuration, you can use the contents of `test/doom.d` as a template. + +## Home-Manager + +### With Flakes + +`File: flake.nix` +```nix +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager.url = "github:nix-community/home-manager"; + nix-doom-emacs.url = "github:nix-community/nix-doom-emacs"; + }; + + outputs = { + self, + nixpkgs, + home-manager, + nix-doom-emacs, + ... + }: { + nixosConfigurations.exampleHost = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + home-manager.nixosModules.home-manager + { + home-manager.users.exampleUser = { ... }: { + imports = [ nix-doom-emacs.hmModule ]; + programs.doom-emacs = { + enable = true; + doomPrivateDir = ./doom.d; # Directory containing your config.el, init.el + # and packages.el files + }; + }; + } + ]; + }; + }; +} +``` + +### Without Flakes + +```nix +{ pkgs, ... }: + +let + doom-emacs = pkgs.callPackage (builtins.fetchTarball { + url = https://github.com/nix-community/nix-doom-emacs/archive/master.tar.gz; + }) { + doomPrivateDir = ./doom.d; # Directory containing your config.el, init.el + # and packages.el files + }; +in { + home.packages = [ doom-emacs ]; +} +``` + + +## NixOS + +`File: flake.nix` +```nix +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nix-doom-emacs.url = "github:nix-community/nix-doom-emacs"; + }; + + outputs = { + self, + nixpkgs, + nix-doom-emacs, + ... + }: { + nixosConfigurations.exampleHost = nixpkgs.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = [ + { + environment.systemPackages = + let + doom-emacs = nix-doom-emacs.packages.${system}.default.override { + doomPrivateDir = ./doom.d; + }; + in [ + doom-emacs + ]; + } + # ... + ]; + }; + }; +} +``` + +You can see all overridable parameters of nix-doom-emacs in [default.nix](../default.nix). + +## Standalone + +### Flake + +```nix +{ + description = "nix-doom-emacs shell"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nix-doom-emacs.url = "github:nix-community/nix-doom-emacs"; + }; + + outputs = { self, nixpkgs, nix-doom-emacs, ... }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + doom-emacs = nix-doom-emacs.packages.${system}.default.override { + doomPrivateDir = ./doom.d; + }; + in + { + devShells.${system}.default = pkgs.mkShell { + buildInputs = [ doom-emacs ]; + }; + }; +} +``` + +### Non-Flake +```nix +{ pkgs ? import { } }: + +let + repo = pkgs.fetchFromGitHub { + owner = "nix-community"; + repo = "nix-doom-emacs"; + rev = ""; + sha256 = ""; + }; + nix-doom-emacs = pkgs.callPackage (import repo) { + doomPrivateDir = ./doom.d; + }; +in +pkgs.mkShell { + buildInputs = [ nix-doom-emacs ]; +} +``` + +# Setup + +## Emacs daemon + +If you use the Home-Manager module, you can enable it via `services.emacs.enable = true;`. The Home-Manager module will do the rest for you. + +If you're not, and you're using a standalone method (NixOS/nix-darwin without Home-Manager) instead, you'll need: + +```nix +services.emacs = { + enable = true; + package = inputs.doom-emacs.packages.${system}.doom-emacs.override { + doomPrivateDir = ./doom.d; + }; +}; +``` + +You can now run `emacsclient -c` to connect to the daemon. + +## Custom Emacs derivations (i.e., PGTK, NativeComp) + +If you're using the Home-Manager module, you can use the `emacsPackage` attribute after applying `emacs-overlay` to your nixpkgs: + +```nix +programs.doom-emacs = { + enable = true; + doomPrivateDir = ./doom.d; + emacsPackage = pkgs.emacsPgtk; +} +``` + +For standalone usage with Flakes: + +```nix +let + # ... + doom-emacs = nix-doom-emacs.packages.${system}.default.override { + doomPrivateDir = ./doom.d; + emacsPackage = pkgs.emacsPgtkNativeComp; + }; +in { + # ... +} +``` + +And for non-Flakes usage: + +```nix +let + # ... + nix-doom-emacs = pkgs.callPackage (import repo) { + doomPrivateDir = ./doom.d; + emacsPackage = pkgs.emacsPgtkNativeComp + }; +in { + # ... +} +``` + +## Updating configuration + +Note that, unlike imperative `Doom Emacs`, we do not have a `doom sync`. Our project builds an Emacs with your Doom configuration embedded in it. `doom sync` just updates packages. +This doesn't mean that you can't update your packages and configuration, obviously: + +To update your Doom Emacs config, you simply rebuild your configuration. For example, in NixOS you can use `nixos-rebuild switch` (or `home-manager switch` if you use Home-Manager standalone). nix-doom-emacs will do everything else for you. + +In an imperative environment, Doom updates can break Emacs with no easy way to roll back. +nix-doom-emacs moves the moving parts of your Emacs installation into the Nix build sandbox. + +## Building third-party Emacs packages + +Though beyond the scope of this document, [`trivialBuild`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/emacs/trivial.nix) is a nixpkgs function to trivially build Emacs packages. You can use it to build e.g. local packages or packages hosted on Git repositories. There is also a family of functions in nixpkgs which are made to build Emacs packages, such as: + +- [`generic`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/emacs/generic.nix): This is the "base" function which all the other build functions are derived from +- [`elpaBuild`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/emacs/elpa.nix): For ELPA packages +- [`melpaBuild`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/emacs/elpa.nix): For MELPA packages + +To find examples of how they're used, try to [search nixpkgs](https://github.com/NixOS/nixpkgs/search) for usages of them. + +# Support + +If you encounter any issues while using nix-doom-emacs, you can find some of us in the [Matrix room](https://matrix.to/#/#doom-emacs:nixos.org).