Jotain is a modern, modular Emacs configuration managed with Nix Flakes, emphasizing performance and reproducible development. It provides a complete development environment with LSP support, modern completion (Vertico/Corfu), Git integration (Magit), and sensible defaults.
- **Reproducible:** Managed by a Nix Flake for consistent development environments.
- **Modular:** Configuration is split into logical modules for easy customization.
- **Performant:** `early-init.el` is optimized for fast startup times.
- **Integrated:** Comes with a home-manager module for easy installation and configuration.
- **Comprehensive:** Includes a wide range of packages for development, writing, and more.
- **Well-tested:** A comprehensive testing suite ensures the stability of the configuration.
Add Jotain to your `flake.nix` and `home-manager` configuration:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
jotain.url = "github:Jylhis/jotain";
};
outputs = { nixpkgs, home-manager, jotain, ... }: {
homeConfigurations."<your-username>" = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [
jotain.homeModules.default
{
programs.jotain.enable = true;
}
];
};
};
}By default, Jotain runs Emacs as a systemd/launchd service.
- Check status: `systemctl –user status emacs.service`
- Restart after config changes: `systemctl –user restart emacs.service`
- View logs: `journalctl –user -u emacs.service`
- Connect to running daemon:
- `emacsclient -c` (New GUI frame)
- `emacsclient -t` (Terminal)
| Key | Action |
|---|---|
C-x g | Magit status |
C-x p f | Project find file |
C-x b | Switch buffer (consult) |
C-s | Search in buffer |
M-. | Go to definition |
M-, | Go back |
C-c t | Toggle between light and dark themes |
C-x j | Toggle window split direction |
C-c u/r | Winner undo/redo window configurations |
- `programs.jotain.enable`: (boolean, default: `false`) Enable Jotain Emacs configuration.
- `programs.jotain.enableDaemon`: (boolean, default: `true`) Run Emacs as a systemd/launchd service.
- `programs.jotain.includeRuntimeDeps`: (boolean, default: `true`) Install runtime dependencies (LSP servers, CLI tools, fonts).
- `programs.jotain.extraPackages`: (function, default: `epkgs: []`) Add extra Emacs packages.
programs.jotain.extraPackages = epkgs: [ epkgs.pdf-tools epkgs.org-roam ];
You can add your own custom elisp code to `~/.config/emacs/custom.el`. This file is automatically loaded if it exists and will persist across rebuilds.
To access all project-specific tools and dependencies, enter the Nix development shell:
nix developThe environment is isolated, using a `.dev-home/` directory for Emacs’s configuration files.
The `justfile` provides commands for common development tasks:
just test-smoke # Ultra-fast smoke tests (< 1 second)
just test-fast # Fast unit tests (< 5 seconds)
just test # Full ERT test suite
just test-all # ERT + NMT module tests (excludes VM)
just build # Build Emacs package
just emacs-dev # Run Emacs with project config (isolated, safe)- elisp/: Feature modules (core, ui, completion, programming, git, etc.)
- tests/: ERT unit tests (test-*.el)
- nmt-tests/: Nix module integration tests
- nix/lib/: Runtime dependencies and helpers
- nix/modules/: Home-manager and NixOS modules
- Add the package to the `epkgs` list in `default.nix`.
- Add a `use-package` configuration in the appropriate `elisp/*.el` file.
- Run `just test` to verify.
For runtime dependencies (LSP servers, CLI tools, fonts, tree-sitter grammars), add them to `nix/lib/runtime-deps.nix`.
- Smoke tests: `:tags ‘(smoke critical)`
- Fast tests: `:tags ‘(fast unit)`
- Unit tests: `:tags ‘(unit)`
- Integration tests: `:tags ‘(integration slow)`
Tests are automatically loaded from `tests/test-all.el`.
- Emacs not finding LSP server: Check if `includeRuntimeDeps = true` or install the server manually.
- Fonts not displaying correctly: Ensure `fonts.fontconfig.enable = true` in your home-manager configuration.
- Daemon not starting: Check the service status and logs.
- Configuration not applying: Restart the daemon: `systemctl –user restart emacs.service`.