Documentation Index
Fetch the complete documentation index at: https://docs.jylhis.com/llms.txt
Use this file to discover all available pages before exploring further.
Modules
Jotain’s Elisp configuration is split acrosslisp/init-*.el, one file per concern. Each file is self-contained: a package that only exists to enhance a built-in (e.g. dirvish → dired, magit → vc, corfu → completion-preview) lives in the same file as the built-in it enhances. There is no “builtins.el” / “third-party.el” split.
Conventions
- Every module file is named
init-<concern>.elunderlisp/. - Every file starts with a
lexical-binding: tcookie. - Every file ends with
(provide 'init-<concern>). - Modules are loaded in order from
init.el. use-package-always-ensureist(set inearly-init.el), so everyuse-packageblock defaults to “install if missing”. Built-ins must opt out with:ensure nil. Packages provided by Nix use:ensure nil— Nix puts them onload-path, souse-packagefinds them without touching the network.- User options (
defcustomvariables) are set viasetopt, notsetq, so the:setcallback and:typevalidation run.
Load order
init.el loads modules in this order:
Core modules
init-core
GC, encoding, and the sane-defaults baseline. Restores gc-cons-threshold to 16 MiB after the early-init bump; pauses GC entirely while the minibuffer is open; forces UTF-8 everywhere; enables save-place-mode, recentf, savehist, repeat-mode, uniquify, ibuffer as the default buffer list, global-auto-revert-mode. Defines jotain-var-dir and the jotain-var-file helper, and themes the built-in state-file variables (recentf-save-file, savehist-file, save-place-file, bookmark-default-file, auto-save-list-file-prefix) to live under var/. Other modules use the same helper to keep their own state (keyfreq, logview, forge, transient) in the same place. Also contains the macOS modifier-key fix (Cmd→Meta, Option→Super, right Option untouched for special characters). Sets read-extended-command-predicate to filter M-x candidates by major mode; untagged commands are still shown, and typing a full command name always runs it regardless of the filter.
init-keys
Global bindings only — per-package bindings live in the relevant use-package block. Unbinds C-z / C-x C-z (no accidental suspend on GUI), binds M-o to other-window, enables windmove-default-keybindings (Shift + arrows), defines jotain-toggle-window-split on C-x j for rotating a two-window layout, and ships a window-resize repeat-map so C-x ^ ^ ^ keeps enlarging without re-pressing C-x. Also registers which-key-add-key-based-replacements for the cross-cutting C-c / C-x prefixes (C-c n org-roam, C-c r eglot-refactor, C-c o combobulate, C-x P project, etc.) so the prefix menus surface short noun-phrase labels instead of bare command names. See Keybindings for the full namespace map and Ergonomics for the repeat-maps rationale.
init-ui
Appearance. Uses modus-operandi-tinted and modus-vivendi-tinted (user-customisable via jotain-theme-light / jotain-theme-dark), with auto-dark-mode flipping between them based on the system appearance. Installs doom-modeline, picks the first available font from jotain-font-preferences (JetBrains Mono Nerd Font → Iosevka Nerd Font → DejaVu Sans Mono), enables display-line-numbers, pixel-scroll-precision-mode, hl-line-mode, show-paren-mode, built-in which-key, nerd-icons integrations for dired/ibuffer/corfu/marginalia, hl-todo, breadcrumb, pulsar, rainbow-delimiters, indent-bars. Also enables global-kkp-mode (Kitty Keyboard Protocol) and clipetty for OSC 52 clipboard support through SSH + tmux.
init-help
Built-in help tweaks (help-window-select) plus helpful for richer describe-* buffers. See Finding Information in Emacs for day-to-day usage.
init-docs
Makes the bundled Jotain Info manual (jotain.info, generated by nix build .#info) discoverable from C-h i. For NixOS / nix-darwin / Home Manager users this is already wired up at the Nix layer: the Emacs wrapper pre-sets INFOPATH, so no Elisp is needed — this module is the source-checkout fallback. After just info, result-info/share/info is added to Info-directory-list; C-h i d m Jotain RET opens the manual. JOTAIN_INFO_DIR overrides the search.
init-editing
Baseline editing primitives: electric-pair-mode, delete-selection-mode, whitespace-mode, undo settings, region tools.
init-completion
The vertico stack on the minibuffer side, corfu + cape on the in-buffer side, plus the built-in minibuffer tweaks they rely on. All configured in one file because touching one nearly always means touching the others. C-s is deliberately left as isearch-forward; use M-s l for consult-line when you want the consult UI.
init-navigation
dired and dirvish in the same file, along with project, winner-mode, and directional navigation.
init-vc
vc pinned to Git only (other backends are a slow startup tax), magit with refined hunks and worktrees in magit-status, magit-todos, forge (configured with the built-in sqlite backend, emacsql-sqlite-builtin), diff-hl (including diff-hl-flydiff-mode for pre-save indicators), smerge-mode helpers, and ediff with sane window setup.
init-prog
The shared substrate for programming modes: prog-mode hooks, treesit setup, eglot, flymake, eldoc, apheleia for format-on-save, compile. Per-language eglot-ensure hooks live here so all LSP wiring is in one place; per-language mode settings live in init-lang-*.el. When the rass binary (rassumfrassum, shipped in the devenv shell) is on PATH, tsx-ts-mode / typescript-ts-mode / typescript-mode buffers are routed through it to run typescript-language-server alongside whichever of eslint-lsp and tailwindcss-language-server are also on PATH, and Python buffers run the bundled rass python preset (basedpyright + ruff) when both binaries are present; any missing prerequisite makes eglot fall back to its built-in single-server lookup, so projects using pylsp / pyright / unguarded tsserver keep working unchanged. Also provides jotain-sonarlint for on-demand SonarLint analysis via the sonarlint-ls language server — SonarCloud connected mode is configured per-project via eglot-workspace-configuration in .dir-locals.el.
init-project
Two complementary project command systems: projection (.dir-locals.el-backed commands exposed via C-x P, auto-detected from Makefiles/justfiles/Cargo.toml/etc) and compile-multi (per-major-mode named compile commands like “go test”, “pytest file”, “nix flake check”). They overlap but neither fully covers the other.
init-ai
AI assistants. claude-code-ide on C-c C-' for agentic multi-file edits via the Claude Code CLI. gptel on C-c RET (send) / C-c M-RET (menu) with three backends configured: Anthropic (default, claude-sonnet-4), Google Gemini, and a local Ollama instance (no key needed). mcp is loaded after gptel for Model Context Protocol tool use. API keys resolve from the environment (ANTHROPIC_API_KEY / GEMINI_API_KEY) first, then fall back to auth-source — auth-source-1password (see init-systems) makes that transparent.
init-shell
eshell, vterm, and comint together — shells have their own input handling, history, prompts, and rendering, so grouping them lets the rules be coordinated in one place.
init-systems
Sysadmin tools: SOPS-encrypted file editing, logview for log files, and auth-source-1password as an auth-source backend so magit/forge, gptel, smtpmail, etc. all resolve credentials against the 1Password vault transparently.
init-tracking
Passive usage instrumentation. keyfreq counts command frequency (M-x keyfreq-show), wakatime-mode reports heartbeats to a Wakatime/Wakapi server (guarded by :if on wakatime-cli + WAKATIME_API_KEY, so it is a no-op if either is missing), and activity-watch-mode is installed but off by default — enable with M-x global-activity-watch-mode.
init-writing
Prose editing: jinx for spell-checking, markdown-mode, denote for notes, pdf-tools. Org is big enough to earn its own file.
init-org
org-mode, org-modern, capture templates, agenda, and friends. Binds C-c a → org-agenda, C-c c → org-capture, C-c l → org-store-link.
Language modules
Eachinit-lang-*.el file pins :mode regexes and provides font-lock for a group of related languages. Formatter configuration is centralised through apheleia in init-prog.el; LSP server hooks live in init-prog.el too.
init-lang-nix—nix-ts-mode. Formatting via apheleia (which ships anixfmtentry).init-lang-rust—rust-ts-mode(built-in) plus Cargo command wrappers.init-lang-python—python-ts-mode(built-in), the interpreter set topython3. The LSP server (pyright/basedpyright/ruff-lsp) comes from the project environment, not from this config.init-lang-web—typescript-ts-mode,tsx-ts-mode, CSS, HTML, JSON, and related tree-sitter modes.init-lang-devops— Dockerfile, docker-compose, Terraform (*.tf), gitlab-ci, justfile, Ansible. Also exposes thedockerMagit-style TUI onC-c dand ajotain-docker-backenddefcustom ('podmanby default, set to'dockerfor classic Docker) that switches the runtime command, compose command, and TRAMP method.init-lang-data— YAML, CSV (withcsv-align-mode), SQL (sql-indent), Jinja2, gnuplot.init-lang-systems— Go (go-mode), C/C++ (cc-mode), CMake, Haskell.
Adding a new module
- Create
lisp/init-<concern>.elwith the usual Elisp headers and alexical-binding: tcookie. - End the file with
(provide 'init-<concern>). - Add a
(require 'init-<concern>)line ininit.elat the appropriate point in the load order. - Run
just checkto confirm the parser is happy, thenjust compileto catch warnings.