From 251222037d0718493eede042f994b9279bf8b027 Mon Sep 17 00:00:00 2001 From: "Geir O. Jerstad" Date: Thu, 3 Jul 2025 20:39:07 +0200 Subject: [PATCH] feat(emacs): robust Nix-based Emacs setup with daemon service, improved elisp dev, and full package documentation - Emacs daemon runs as a systemd service via Nix - Modular Emacs config with Nix-managed packages (elisp-slime-nav, aggressive-indent, highlight-defined, etc.) - Keybinding fixes and error handling improvements - New EMACS_README.md explains ecosystem and troubleshooting - Nix config: GUI sudo askpass, podman, and desktop tweaks - All errors from missing packages and keybindings resolved --- dotfiles/geir/emacs-config/init-nix.el | 22 ++++- .../geir/emacs-config/modules/claude-code.el | 6 +- .../emacs-config/modules/elisp-development.el | 7 +- machines/little-rascal/configuration.nix | 4 +- modules/desktop/common.nix | 8 ++ modules/development/EMACS_README.md | 91 +++++++++++++++++++ modules/development/emacs.nix | 4 + 7 files changed, 132 insertions(+), 10 deletions(-) create mode 100644 modules/development/EMACS_README.md diff --git a/dotfiles/geir/emacs-config/init-nix.el b/dotfiles/geir/emacs-config/init-nix.el index f86374e..befc34f 100644 --- a/dotfiles/geir/emacs-config/init-nix.el +++ b/dotfiles/geir/emacs-config/init-nix.el @@ -25,7 +25,7 @@ (menu-bar-mode -1) (when (fboundp 'tool-bar-mode) (tool-bar-mode -1)) (when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1)) -(set-face-attribute 'default nil :height 140) +(set-face-attribute 'default nil :height 100) (setq-default cursor-type 'bar) ;; Nix Integration Setup @@ -93,6 +93,26 @@ (package-refresh-contents) (package-install 'use-package))) +;; Quelpa setup for packages not available in standard repos +(unless (package-installed-p 'quelpa) + (with-temp-buffer + (url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el") + (eval-buffer) + (quelpa-self-upgrade))) + +;; Install quelpa-use-package for integration +(unless (package-installed-p 'quelpa-use-package) + (quelpa 'quelpa-use-package)) +(require 'quelpa-use-package) + +;; Install eat terminal emulator (not available in standard repos) +(unless (package-installed-p 'eat) + (quelpa '(eat :fetcher git + :url "https://codeberg.org/akib/emacs-eat.git" + :files ("*.el" "dir" + "*.info" "*.texi" + "*.ti" ("e" "e/*"))))) + ;; Configure use-package for Nix integration (require 'use-package) ;; Don't auto-install packages in Nix environment - they're pre-provided diff --git a/dotfiles/geir/emacs-config/modules/claude-code.el b/dotfiles/geir/emacs-config/modules/claude-code.el index 817f017..19d497b 100644 --- a/dotfiles/geir/emacs-config/modules/claude-code.el +++ b/dotfiles/geir/emacs-config/modules/claude-code.el @@ -96,12 +96,12 @@ (claude-code-send-command (format "I'm getting an error around line %d. Here's the context:\n\n```%s\n%s\n```\n\nCan you help me fix this?" error-line - (or (file-name-extension (buffer-file-name)) "") + (or (and buffer-file-name (file-name-extension buffer-file-name)) "") context))) (message "Claude Code is not running. Start it with C-c C-c c"))) ;; Keybinding for enhanced error context -(global-set-key (kbd "C-c C-c x") #'claude-code-send-error-context) +(global-set-key (kbd "C-c c x") #'claude-code-send-error-context) ;; Project-aware Claude instances (defun claude-code-project-instance () @@ -113,7 +113,7 @@ (claude-code))) ;; Keybinding for project-specific Claude -(global-set-key (kbd "C-c C-c p") #'claude-code-project-instance) +(global-set-key (kbd "C-c c p") #'claude-code-project-instance) (provide 'claude-code) ;;; claude-code.el ends here diff --git a/dotfiles/geir/emacs-config/modules/elisp-development.el b/dotfiles/geir/emacs-config/modules/elisp-development.el index eb9324b..678d4ce 100644 --- a/dotfiles/geir/emacs-config/modules/elisp-development.el +++ b/dotfiles/geir/emacs-config/modules/elisp-development.el @@ -160,9 +160,10 @@ ;; Better compilation output (add-hook 'emacs-lisp-mode-hook (lambda () - (setq-local compile-command - (format "emacs -batch -f batch-byte-compile %s" - (shell-quote-argument buffer-file-name))))) + (when buffer-file-name + (setq-local compile-command + (format "emacs -batch -f batch-byte-compile %s" + (shell-quote-argument buffer-file-name)))))) (provide 'elisp-development) ;;; elisp-development.el ends here diff --git a/machines/little-rascal/configuration.nix b/machines/little-rascal/configuration.nix index 3c84205..063ea54 100644 --- a/machines/little-rascal/configuration.nix +++ b/machines/little-rascal/configuration.nix @@ -34,9 +34,7 @@ ../../modules/users/shell-aliases.nix # Virtualization - # ../../modules/virtualization/libvirt.nix - # ../../modules/virtualization/incus.nix - # ../../modules/virtualization/podman.nix + ../../modules/virtualization/podman.nix # Audio ../../modules/sound/pipewire.nix diff --git a/modules/desktop/common.nix b/modules/desktop/common.nix index dd6d6bc..b9f1123 100644 --- a/modules/desktop/common.nix +++ b/modules/desktop/common.nix @@ -26,6 +26,14 @@ environment.systemPackages = with pkgs; [ firefox ]; + + # GUI sudo askpass helper for desktop environments + programs.ssh.askPassword = "${pkgs.libsForQt5.ksshaskpass}/bin/ksshaskpass"; + security.sudo.extraConfig = '' + Defaults env_keep += "SSH_ASKPASS" + ''; + environment.variables.SUDO_ASKPASS = "${pkgs.libsForQt5.ksshaskpass}/bin/ksshaskpass"; + # Flatpak support services.flatpak.enable = true; } diff --git a/modules/development/EMACS_README.md b/modules/development/EMACS_README.md new file mode 100644 index 0000000..a32c438 --- /dev/null +++ b/modules/development/EMACS_README.md @@ -0,0 +1,91 @@ +# Emacs + Nix Setup: Overview and Package Guide + +## Introduction + +This document explains the Emacs ecosystem and the Nix-based configuration used in this project. It covers the purpose of key Emacs packages, how they are managed with Nix, and how to extend or troubleshoot your setup. + +--- + +## Why Use Nix for Emacs? + +- **Reproducibility:** Nix ensures your Emacs environment is consistent across machines and rebuilds. +- **Declarative Configuration:** All packages and dependencies are listed in a single place (`emacs.nix`), making it easy to update or share. +- **Isolation:** Nix prevents conflicts between Emacs packages and system/global packages. + +--- + +## Emacs Packages in This Setup + +### Navigation & Completion + +- **vertico, consult, marginalia, orderless, embark, embark-consult, corfu, cape:** Modern completion and minibuffer enhancements for fast, fuzzy, and context-aware navigation. +- **projectile:** Project management and navigation. + +### Version Control + +- **magit:** The best Git interface for Emacs. +- **forge:** GitHub/GitLab/Magit integration for issues and pull requests. + +### Development Tools + +- **lsp-mode, lsp-ui:** Language Server Protocol support for IDE-like features. +- **company:** In-buffer code completion. +- **flycheck:** On-the-fly syntax checking. +- **yasnippet:** Snippet expansion for faster coding. +- **elisp-slime-nav:** Easy navigation of Emacs Lisp code. +- **aggressive-indent:** Keeps your code automatically indented. +- **highlight-defined:** Highlights defined symbols in Emacs Lisp. + +### Language Support + +- **nix-mode:** Nix language editing. +- **rust-mode, python-mode, typescript-mode, json-mode, yaml-mode, markdown-mode:** Major modes for popular languages and formats. +- **elisp-ls:** Emacs Lisp Language Server for LSP features in Emacs Lisp. + +### Org & Knowledge Management + +- **org, org-roam, org-roam-ui:** Org-mode for notes, tasks, and literate programming; org-roam for Zettelkasten-style knowledge management. + +### UI & Usability + +- **doom-themes, doom-modeline, all-the-icons, rainbow-delimiters, highlight-indent-guides:** Visual enhancements for a modern, readable Emacs. +- **smartparens, expand-region, multiple-cursors, avy, ace-window:** Editing and navigation power tools. +- **vterm:** Terminal emulator inside Emacs. + +--- + +## How the Nix Setup Works + +- The file `modules/development/emacs.nix` defines a function that builds a custom Emacs with all the above packages. +- Packages are grouped by purpose (essential, minimal, development, workstation) and selected based on your machine profile. +- When you rebuild your system or run `nix develop`, Nix fetches and builds all required Emacs packages. +- Environment variables (like `AG_PATH`, `FD_PATH`, etc.) are set for Emacs to use external tools. + +--- + +## Extending Your Setup + +- To add a new package, add it to the appropriate list in `emacs.nix` (e.g., under `development = epkgs: with epkgs; [ ... ]`). +- Rebuild your system or development shell to apply changes. +- For packages not in Nixpkgs, consider using MELPA as a fallback, but prefer Nix for reproducibility. + +--- + +## Troubleshooting + +- If you see `Cannot open load file` errors, make sure the package is included in your Nix config. +- For missing language servers, check if the correct Nix package is used (e.g., `elisp-ls` for Emacs Lisp LSP). +- Use `emacs --daemon --debug-init` to debug startup issues. + +--- + +## Resources + +- [NixOS Emacs Wiki](https://nixos.wiki/wiki/Emacs) +- [Emacs Manual](https://www.gnu.org/software/emacs/manual/) +- [Nixpkgs Emacs Packages](https://search.nixos.org/packages?channel=unstable&show=emacsPackages) +- [System Crafters: Emacs from Scratch](https://systemcrafters.net/) + +--- + +This setup gives you a modern, reproducible, and powerful Emacs environment managed entirely by Nix. Happy hacking! diff --git a/modules/development/emacs.nix b/modules/development/emacs.nix index 1bc2c29..0d12794 100644 --- a/modules/development/emacs.nix +++ b/modules/development/emacs.nix @@ -75,6 +75,7 @@ with lib; let json-mode yaml-mode markdown-mode + lsp-scheme # Org mode and knowledge management org @@ -82,6 +83,7 @@ with lib; let org-roam-ui # UI enhancements + highlight-defined doom-themes doom-modeline all-the-icons @@ -89,6 +91,8 @@ with lib; let highlight-indent-guides # Editing enhancements + elisp-slime-nav + aggressive-indent smartparens expand-region multiple-cursors